1 while 循环语句
>>>a, b = 0, 1
>>> while a < 10:
... print(a)
... a, b = b, a+b
while 循环只要条件(这里指: a < 10 )保持为真就会一直执行。
Python 和 C 一样,任何非零整数都为真,零为假。
这个条件也可以是字符串或列表的值,事实上,任何序列都可以;长度非零就为真,空序列则为
假。示例中的判断只是最简单的比较。
循环体是缩进的 :缩进是 Python 组织语句的方式。同一块语句的每一行的缩进相同。
while 语句格式如下
while <条件判断>:
语句块
循环语句后面都可以跟else语句。
while … else … 先进行 while 循环,循环结束后再执行 else 下的语句。
注意,当 while 的条件永远为 True 是就是一个无限循环。不注意容易使程序进入死循环。
break 与 continue 退出循环,在下面for循环再说。
2 if语句
2.1 if 语句
>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
...
More
if 语句包含零个或多个 elif 子句,及可选的 else 子句。关键字 ‘ elif ‘ 是 ‘else if’ 的缩写,适
用于避免过多的缩进。可以把 if … elif … elif … 序列看作是其他语言中 switch 或 case 语句
的替代品。
如果你要将同一个值与多个常量进行比较,或是要检查特定类型或属性,你可能会发现 match 语句是很有用的。
2.2 match 语句
match 语句接受一个表达式并将它的值与以一个或多个 语句块(case)形式给出的一系列模式进行比较。 这在表面上很类似 C, Java 或 JavaScript (以及许多其他语言) 中的 switch 语句,但它还能够从值中提取子部分 (序列元素或对象属性) 并赋值给变量。
最简单的形式是将一个目标值与一个或多个字面值进行比较,如果没有任何 case 语句匹配成功,则任何分支都不会被执行:
1.def http_error(status):
2. match status:
3. case 400:
4. return "Bad request"
5. case 404:
6. return "Not found"
7. case 418:
8. return "I'm a teapot"
9. case _: # 注意最后一个代码块: “变量名” _ 被作为通配符并必定会匹配成功。
10. return "Something's wrong with the internet"
可以使用 | (“ or ”)在一个模式中组合几个字面值,比如上面示例可以改写部分代码如下:
1.def http_error(status):
2. match status:
3. case 401 | 403 | 404:
4. return "Not allowed"
match和case的组织模式可以类似于解包赋值,并可被用于绑定变量:
1. # point is an (x, y) tuple
2. match point:
3. case (0, 0):
4. print("Origin")
5. case (0, y):
6. print(f"Y={y}")
7. case (x, 0):
8. print(f"X={x}")
9. case (x, y):
10. print(f"X={x}, Y={y}")
11. case _:
12. raise ValueError("Not a point")
仔细研究上面代码! 第一个case块有两个字面值,可以看作是上面所示字面值模式的扩展。 但接下来的两个case块结合了一个字面值和一个变量,而变量绑定 了一个来自目标的值 ( point )。 第四个模式捕获了两个值,这使得它在概念上类似于解包赋值 (x, y) = point 。
模式可以任意地嵌套。 例如,如果我们有一个由点组成的短列表,则可以这样匹配它:
1. match points:
2. case []:
3. print("No points")
4. case [Point(0, 0)]:
5. print("The origin")
6. case [Point(x, y)]:
7. print(f"Single point {x}, {y}")
8. case [Point(0, y1), Point(0, y2)]:
9. print(f"Two on the Y axis at {y1}, {y2}")
10. case _:
11. print("Something else")
我们可以向一个case块添加 if 子句,如果为假值,则 match 将继续尝试下一个 case语句块。 请注意值的捕获发生在if语句被求值之前。
1. match point:
2. case Point(x, y) if x == y:
3. print(f"Y=X at {x}")
4. case Point(x, y):
5. print(f"Not on the diagonal")
match语句的一些其他关键特性:
2.2.1 类似于解包赋值,元组和列表模式具有完全相同的含义并且实际上能匹配任意序列。 一个重要的例外是它们不能匹配迭代器或字符串。
2.2.2 序列模式支持扩展解包操作: [x, y, *rest] 和 (x, y, *rest) 的作用类似于解包赋值。 在 * 之后的名称也可以为 _ ,因此 (x, y, *_) 可以匹配包含至少两个条目的序列而不必绑定其余的条目。
2.2.3 映射模式: {“bandwidth”: b, “latency”: l} 会从一个字典中捕获 “bandwidth” 和 “latency” 的值。
与序列模式不同,额外的键会被忽略。
2.2.4 大多数字面值是按相等性比较的,但是单例对象 True , False 和 None 则是按标识号比较的。
3 for 语句
Python 的 for 语句与 C 或 Pascal 中的不同。Python 的 for 语句不迭代算术递增数值,而是迭代列表或字符串等任意序列,元素的迭代顺序与在序列中出现的顺序一致。 例如:
>>> # 示例:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w)) # 打印字符串和它的长度
...
cat 3
window 6
defenestrate 12
for循环遍历某个集合的同时修改该集合的内容,很难获取想要的结果。要在遍历时修改集合的内容,应该遍历该集合的副本或创建新的集合:
# 创建样本集合(一个字典)
users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
# 在副本上重复
for user, status in users.copy().items():
if status == 'inactive':
del users[user]
# 创建新集合
active_users = {}
for user, status in users.items():
if status == 'active':
active_users[user] = status
4 range函数
range() 函数
内置函数 range() 常用于遍历数字序列,该函数可以生成算术级数:
1. >>> for i in range(5):
2. ... print(i)
3. ...
4. 0
5. 1
6. 2
7. 3
8. 4
生成的序列不包含给定的终止数值; range(10) 生成 10 个值,这是一个长度为 10 的序列,其中的元素索引都是合法的。range 可以不从 0 开始,还可以按指定幅度递增(递增幅度称为 ‘步进’,支持负数):
1. >>> list(range(5, 10))
2. [5, 6, 7, 8, 9]
3.
4. >>> list(range(0, 10, 3))
5. [0, 3, 6, 9]
6.
7. >>> list(range(-10, -100, -30))
8. [-10, -40, -70]
range() 和 len() 组合在一起,可以按索引迭代序列(不过,大多数情况下, enumerate() 函数更便捷):
1. >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
2. >>> for i in range(len(a)):
3. ... print(i, a[i])
4. ...
5. 0 Mary
6. 1 had
7. 2 a
8. 3 little
9. 4 lamb
range() 返回对象的操作和列表很像,但其实这两种对象不是一回事。迭代时,该对象基于所需序列返回连续项,并没有生成真正的列表,从而节省了空间。
5 break 、 continue 语句及 else 子句,pass语句
5.1 break 、else子句
break 语句用于跳出最近的 for 或 while 循环。
循环语句支持 else 子句; for 循环中,可迭代对象中的元素全部循环完毕时,或 while 循环的条件为假时,执行else子句; break 语句终止循环时,不执行该子句。 请看下面这个查找素数的循环示例:
1. >>> for n in range(2, 10):
2. ... for x in range(2, n):
3. ... if n % x == 0:
4. ... print(n, '等于', x, '*', n//x)
5. ... break
6. ... else: # 仔细看: else 子句属于 for 循环,不属于 if 语句。
7. ... print(n, '是素数')
8. ...
9. 2 是素数
10. 3 是素数
11. 4 等于 2 * 2
12. 5 是素数
13. 6 等于 2 * 3
14. 7 是素数
15. 8 等于 2 * 4
16. 9 等于 3 * 3
5.2 continue
continue 表示继续执行循环的下一次迭代:
1. >>> for num in range(2, 10):
2. ... if num % 2 == 0:
3. ... print("找到一个偶数", num)
4. ... continue
5. ... print("找到一个奇数", num)
6. ...
7. 找到一个偶数 2
8. 找到一个奇数 3
9. 找到一个偶数 4
10. 找到一个奇数 5
11. 找到一个偶数 6
12. 找到一个奇数 7
13. 找到一个偶数 8
14. 找到一个奇数 9
5.3 pass语句
pass 语句不执行任何操作。语法上需要一个语句,但程序不实际执行任何动作时,可以使用该语句。例如:
>>> while True:
... pass # 等待键盘中断 (Ctrl+C)
下面这段代码创建了一个最小的类:
1. >>> def initlog(*args):
2. ... pass # 创建了一个什么也不做的类
pass 还可以用作函数或条件子句的占位符,让开发者聚焦更抽象的层次。此时,程序直接忽略 pass :
>>> def initlog(*args):
... pass # 今天不太舒服,想起来再写,占好位置!
...