实用Python程序设计MOOC-第三章循环语句

实用Python程序设计MOOC-第三章循环语句

[TOC]

实用Python程序设计MOOC-第三章循环语句

循环语句

有时,需要重复多次执行一系列语句,因此需要循环语句

for循环语句语法

1
2
3
4
for <variable> in <sequence>:
<statements 1>
else:
<statements 2>

依次对sequence中的每个值,执行然后再执行。通常不需要else部分
sequence可以是range(..),也可以是字符串、列表、元组、字典、集合

  • for循环语句测试
1
2
for i in range(5):#[0,5)
print (i)

输出:

1
2
3
4
5
0
1
2
3
4

1
2
for i in range(5,9): #[5,9)
print (i)

输出:

1
2
3
4
5
6
7
8

  • for循环语句测试2
1
2
for i in range(0, 10, 3):#步长3
print(i)

输出

1
2
3
4
0
3
6
9

1
2
for i in range(-10, -100, -30) :
print (i)

输出

1
2
3
-10
-40
-70

  • for循环语句测试3
1
2
for i in range (0):
print(i)

无输出

1
2
for i in range(2,2):
print(i)

无输出

1
2
for i in range(3,12,3):
print(i," ",end="')

输出

1
3 6 9

for循环遍历列表

  • 写法1
1
2
3
a = ['Google', 'Baidu', 'IBM', 'Taobao', 'QQ']
for i in range(len(a)): #len,求列表长度(元素个数)
print(i, a[i])

输出

1
2
3
4
5
0 Google
1 Baidu
2 IBM
3 Taobao
4 QQ

len也可以用来求字符串长度,元组、集合、字典元素个数

1
print(len("abc"))#>>3
  • 写法2
1
2
3
a = ['Google', 'Baidu', 'IBM', 'Taobao', 'QQ']
for i in a:
print(i)

输出

1
2
3
4
Google
Baidu
IBM
Taobao

for循环遍历字符串

1
2
for letter in 'Taobao':
print(letter)

输出

1
2
3
4
5
T
a
o
b
a

break语句

1
2
3
4
5
6
7
8
sites = ["Baidu", "Google", "IBM", "Taobao"] 
for site in sites:
if site == "IBM":
print("OK")
print("site: " + site)
else:
print("No break")
print ("Done!")

输出

1
2
3
4
5
6
7
site: Baidu
site: Google
OK
site: IBM
site: Taobao
No break
Done!

1
2
3
4
5
6
7
8
9
sites = ["Baidu", "Goog1e", "IBM", "Taobao"]
for site in sites: #对sites中的每个值site
if site == "IBM" :
print ("OK")
break #跳出循环
print("site: " + site)
else:
print("No break")
print("Done!")

else子句在循环结束时会执行,但是如果break了,则不会执行

输出

1
2
3
4
site: Baidu
site: Google
OK
Done!

continue语句

1
2
3
4
for letter in ' Taobao':
if letter == 'o': #字母为o时跳过输出
continue #直接跳到下次循环
print('当前字母:', letter)

输出

1
2
3
4
当前字母: T
当前字母: a
当前字母: b
当前字母: a

连续输出26个字母

1
2
for i in range(26):
print(chr(ord("a") + i), end="")

abcdefghi jklmnopqrstuvwxyz
字母的ASCII编码是连续的

字符的编码

ord(x) 求字符x的编码(字符就是长度为1的字符串)
chr(x) 求编码为x的字符

可以用8个连续的0或1(即1个字节)来表示一个字母、数字或标点符号,比如用”00100000”表示空格,用”01100001”表示字母”a”,用”01100010”表示字母”b”,用”01100011”表示字母”c”……。由8个0或者1的组成的串,一共有2^8即256种不同的组合,这就足以表示10个阿拉伯数字以及英语中用到的所有字母和标点符号了。此即为ASCII编码方案。

连续输出0-9

1
2
for i in range(10):
print(chr(ord("0") + i), end="")

0123456789
‘0’-‘9’的ASCII编码是连续的

1
print(chr(ord("A") + 4))	#E

for循环简单例题

例题1 输入n个整数求和

  • 输入
    第一行是整数n,n>=1,后面有n行,每行一个整数

  • 输出
    输出后面那n个整数的和

  • 样例输入
    3
    1
    2

  • 样例输出
    11

  • 提交代码

1
2
3
4
5
n = int(input())
total = 0
for i in range(n): #做n次
total += int(input()) #每次读入一行
print(total)

例题2 从小到大输出n的因子

输入一个正整数,从小到大输出它的所有因子

1
2
3
4
n = int(input())
for x in range(1, n+1):
if n % x == 0:
print(x, " ", end="")

输出

1
2
15↙
1 3 5 15

例题3 从大到小输出n的因子

输入一个正整数m,从大到小输出它的所有因子

1
2
3
4
n = int(input())
for x in range(n, 0, -1): #步长-1
if n % x == 0:
print(x, " ", end="")

输出

1
2
15↙
15 5 3 1

多重循环

循环可以嵌套,形成多重循环:

1
2
3
4
for i in range(n):
...
for j in range(m):
... #内重循环的执行次数一共是n×m次

多重循环例题1 多次求n个数的和

  • 输入
    第一行是整数m,m>=1, 表示有m组数据,接下来就是m组数据
    对于每组数据:
    第一行是整数n,n>= 1
    接下来是n行,每行一个整数

  • 输出
    对每组数据,输出后面那n个整数的和

  • 样例输入
    2
    3
    1
    2
    3
    2
    10
    20

  • 样例输出
    6
    30

  • 提交代码

1
2
3
4
5
6
7
m = int(input())
for i in range(m): #m组数据,所以要处理m次
n = int(input())
total = 0
for i in range(n): #n个数,每个一行,所以要input n次
total += int(input())
print(total)

多重循环例题2 取两个数

给定正整数n和m,在1至n这n个数中,取出两个不同的数,使得其和是m的因子,问有多少中不同的取法。输出这些取法。

思路:穷举1-n这n个数中取两个数的所有取法,对每一种取法,判断其和是不是m的因子

第一个数取1,第二个数分别取2, 3…..n
第一个数取2,第二个数分别取3, 4…..n
….
第一个数取n-2,第二个数分别取n-1,n
第一个数取n-1,第二个数取n

1
2
3
4
5
6
7
8
9
total = 0	#取法总数
lst = input().split()
n, m = int(lst[0]), int(lst[1])
for i in range(1, n): #取第一个数i,共n-1中取法
for j in range(i+1, n+1): #第二个数要比第一个数大,以免取法重复
if m % (i+j) == 0:
print(i, j)
total += 1
print(total)

输出

1
2
3
4
5
6
7
8
9
9 18↙
1 2
1 5
1 8
2 4
2 7
3 6
4 5
7

多重循环中的break

只会跳出当前那重循环,不会跳出多重循环

  • 例题:给定正整数n和m,在1至n这n个数中,取出两个不同的数x、y,使得x<y且x+y是m的因子。要求输出的数对里面,x不重复,且y尽可能小。输出这些取法。
1
2
3
4
5
6
7
lst = input().split()
n, m = int(lst[0]), int(lst[1])
for i in range(1, n): #取第一个数i,共n-1种取法
for j in range(i+1, n+1): #第二个数要比第一个数大,以免取法重复
if m % (i+j) == 0:
print(i,j)
break #后面的j不用再取了,直接换下一个i

输出

1
2
3
4
5
9 18↙
1 2
2 4
3 6
4 5

while循环

  • while循环语法1
1
2
3
4
while 逻辑表达式exp: 
语句组1
else:
语句组2

1)判断 exp 是否为真,若为真,转2),若为假,转3)
2)执行 语句组1,回到 1)
3)执行 语句组2
4)继续往下执行…….

  • while循环语法2
1
2
3
while 逻辑表达式exp:
语句组1
......

1)判断 exp 是否为真,若为真,转2),若为假,转3)
2)执行语句组1,回到1)
3)继续往下执行……

  • while循环例题
1
2
3
4
5
6
count = 0
while count<5:
print(count, "小于5")
count = count + 1
else:
print(count, "大于或等于5")

输出

1
2
3
4
5
6
0小于5
1小于5
2小于5
3小于5
4小于5
5大于或等于5

  • while循环语法3-break
1
2
3
4
5
while True:
...
if exp:
break
...

不停执行,直到exp为真时跳出循环

  • 连续输出26个字母
1
2
3
4
i = 0
while i < 26:
print(chr(ord("a") + i), end="")
i += 1

abcdefqhijklmnoparstuvwxvz 字母的ASCII编码是连续的

  • 例题:输入一个正整数n,从小到大输出它的所有因子
1
2
3
4
5
6
n = int(input())
X = 1
while x<=n:
if n&x == 0:
print(x, " ", end="")
x += 1

输出

1
2
15↙
1 3 5 15

  • 例题:提示用户输入密码,密码不正确则提示不正确,然后要求输入,密码正确则提示成功,然后结束。密码是pku
1
2
3
while (input("请输入密码:") != "pku"):
print("密码不正确!")
print("密码输入成功!")

输出

1
2
3
4
5
6
请输入密码:bba↙
密码不正确!
请输入密码:std↙
密码不正确!
请输入密码:pku↙
密码输入成功!

  • 输入三个整数,求它们的最小公倍数

枚举法,一个个试

1
2
3
4
5
6
7
8
s = input().split()
x,y,z = int(s[0]), int(s[1]), int(s[2])
n = 1
while True:
if n % x == O and n % y == 0 and n % z == 0:
print(n)
break
n = n + 1
1
2
3
4
5
6
s = input().split()
x,y,z = int(s[0]), int(s[1]), int(s[2])
n = 1
while not (n % x == O and n % y == 0 and n % z == 0):
n += 1
print(n)
1
2
3
4
5
6
7
8
s = input().split()
x,y,z = int(s[0]), int(s[1]), int(s[2])
n = m = max(x, y, z) #从三者里面最大的开始试
while True:
if n % x == O and n % y == 0 and n % z == 0:
print(n)
break
n = n + m #没必要一个个试,而是每间隔m个试一下(还可进一步改进)

异常处理

用whi le语句和异常处理进行输入

在0penjudge做题时,有些题目,输入数据没有结束标志,也不告诉你有多少数据。

例如:

输入若干行,每行若干整数,求所有整数的最大值

输入样例:
152393
87 6
34

输出样例:
87

如何判断输入结束,就是需要解决的问题

1
2
3
4
5
6
7
8
9
10
11
12
s = input()
lst = s.split()
maxV = int(lst[0])
try:
while True:
lst = s.split()
for x in lst:
maxV = max(maxV, int(x))
s = input() #输入数据已经没有了还执行input,会产生异常
except:
pass #pass语句啥也不做
print(maxV)

输出

1
2
3
4
5
6
15 23 6↙
15 5 3 1↙
3 4↙
Ctrl+Z↙ 代表输入停止

23

异常处理结构

1
2
3
4
try:
<语句组1>
except:
<语句组2>

如果在<语句组1>执行过程中出现了异常(runtime error), 程序立即从语句组1中跳出,去执行<语句组2>,然后再继续往下执行。如果<语句组1>执行正常完,则程序继续往下执行,不会执行<语句组2>

常见的异常有:
1)不合适的转换,例如int(“abc”) int(“23. 34”) float (“abc”)
2)输入已经结束(已经没有输入数据了)后,还执行input(),在openjudge做题常见
3)除法除数为0
4)整数和字符串相加

1
2
3
4
5
6
7
8
try:
n = int(input())
print("hello")
a = 100/n
print(a)
except:
print("error")
print("end")

输出

1
2
3
4
5
5↙

hello
20.2
end

1
2
3
4
5
0↙

hello
error
end
1
2
3
4
abc↙

error
end

循环综合例题

例题1.求斐波那契数列第k项

菲波那契数列是指这样的数列:数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。给出一个正整数k,要求菲波那契数列中第k个数是多少。

  • 输入
    输入一行,包含一个正整数k。

  • 输出:
    输出一行,包含一个正整数,表示菲波那契数列中第k个数的大小。

  • 样例输入
    19

  • 样例输出
    4181

  • 解法一,迭代,不停地由已知推未知

1
2
3
4
5
6
7
8
k = int(input())
if k == 1 or k == 2
print(1)
else:
a1 = a2 = 1
for i in range(k-2):
a1,a2 = a2, a1+a2
print(a2)

例题2.求阶乘的和

给定正整数n,求不大于n的正整数的阶乘的和(即求1!+2!+3!+…+n!)

  • 输入
    输入有一行,包含一个正整数n (1 < n < 12)。

  • 输出
    输出有一行:阶乘的和。

  • 样例输入
    5

  • 样例输出
    153

  • 解法1

1
2
3
4
5
6
7
8
n = int(input())
s = 0
for i in range(1, n+1)
f = 1 #存放i阶乘
for j in range(i, i+1):
f *= j #此操作一共做1+2+3+...+n次
s += f
print(s)

重复计算多。比如算3!时算了一遍123,算4!时又算一遍123
改进: 123只要算一遍就应该记下来,下次算4!直接用它

  • 解法2
1
2
3
4
5
6
7
8
n = int(input())
s,f = 0,1 #s是第几个数,f表示阶乘
for i in range (1,n+1):
f *= i
s += f
print(s)

f值变化过程: 1*2, 1*2*3, 1*2*3*4 ......

例题3.输入正整数n(n>=2),求不大于n的全部质数

  • 解法1
1
2
3
4
5
6
7
8
9
n = int(input())
for i in range(2, n+1): #每次判断i是否是质数
ok = True #开始假设i是质数
for k in range(2, i)
if i % k == 0
ok == False
break
if ok:
print(i)

此解法做了没必要的尝试,偶数,以及k大于i的平方根后就不必再试

  • 解法2
1
2
3
4
5
6
7
8
9
10
11
12
n = int(input())
print(2)
for i in range(3, n+1, 2):
ok = True
for k in range(3, i, 2):
if i % k == 0:
ok = False
break
if k*k >i:
break
if ok:
print(i)
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2022/09/16/实用Python程序设计MOOC-第三章循环语句/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
好用、实惠、稳定的梯子,点击这里