本文系官方文档翻译之作,不当之处,敬请原谅!
range()函数
如果需要遍历一个数字序列,可以使用内置的range函数。该函数会生成等差序列。
|
1
2
3
|
range(5)# 范围[0, 5)
range(5,10)# 范围[5, 10)
range(0,10,3)# [0, 3, 6, 9]
|
若要依据索引迭代序列,可以使用range()和len()
|
1
2
3
|
a =[\'Mary\',\'had\',\'a\',\'little\',\'lamb\']
for idx in range(len(a)):
print(idx, a[idx])
|
在这种情况下,使用enumerate()函数会更加方便
|
1
2
|
for idx, val in enumerate(a):
print(idx, val)
|
range()返回的对象的行为在很多方面很像一个列表,但实际上它并不是列表。当你迭代它的时候它会依次返回期望序列的元素,但是它不会真正产生一个列表,因此可以节省空间
for/while...else
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#----------------------------------------------------------------------def test_for_else():
"""while/for...else
当循环是因为迭代完整个列表(for)或循环条件不成立(while)终止,
而不是由break语句终止时,else子句将被执行
"""
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, \'equal\', x, \'*\', n//x)
break
else: # for x in range(2, n)的else子句
# loop fell through without finding a factor
print(n, \'is a prime number\')
|
上述代码的输出结果如下:
|
1
2
3
4
5
6
7
8
|
2 is a prime number
3 is a prime number
4 equal 2 * 2
5 is a prime number
6 equal 2 * 3
7 is a prime number
8 equal 2 * 4
9 equal 3 * 3
|
与循环一起使用的 else 子句更类似于 try 语句的 else 子句而不是 if 语句的 else 子句:try 语句的 else 子句在没有任何异常发生时运行,而循环的 else 子句在没有 break 发生时运行。
默认参数值
最有用的形式是指定一个或多个参数的默认值。这种方法创建的函数被调用时,可以带有比定义的要少的参数。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#----------------------------------------------------------------------def ask_ok(prompt, retries=4, complaint=\'Yes or no, please !\'):
while True:
ok = input(prompt)
if ok in (\'y\', \'ye\', \'yes\'):
return True
if ok in (\'n\', \'no\', \'nop\', \'nope\'):
return False
retries = retries - 1
if retries < 0:
raise OSError(\'uncooperative user\')
print(complaint)
#----------------------------------------------------------------------def test_default_param():
ask_ok (\'Do you really want to quit ?\')
ask_ok (\'OK to overwrite the file ?\', 2)
ask_ok (\'OK to overwrite the file ?\', 2, \'Come on, only yes or no !\')
|
例如,下面的函数在后续调用过程中会累积传给它的参数。
|
1
2
3
4
5
6
|
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
|
结果如下:
|
1
2
3
|
[1]
[1, 2]
[1, 2, 3]
|
如果不想默认值在随后的调用中共享,可以像这样编写函数:
|
1
2
3
4
5
|
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
|
遍历的技巧
循环迭代字典的【key】/【value】/【key/value】
|
1
2
3
4
5
6
7
8
9
10
11
12
|
def test_iterate_dict():
""""""
knights = {\'gallahad\': \'the pure\', \'robin\': \'the brave\'}
# 遍历[key, value]
for key, val in knights.items():
print(key, val)
# 遍历key
for key in knights.keys():
print(key)
# 遍历value
for val in knights.values():
print(val)
|
遍历序列,同时获得索引和对应的值
|
1
2
3
4
5
6
7
|
def test_for():
""""""
a = [\'Mary\', \'had\', \'a\', \'little\', \'lamb\']
for idx in range(len(a)):
print(idx, a[idx])
for idx, val in enumer
|
同时遍历两个或者更多序列,使用zip()函数可以成对地读取元素
|
1
2
3
4
5
6
|
def test_zip():
""""""
questions = [\'name\', \'quest\', \'favorite color\']
answers = [\'lancelot\', \'the holy grail\', \'blue\']
for q, a in zip(questions, answers):
print(\'What is your {0}? \n It is {1}.\'.format(q, a))
|
要反向遍历一个序列,首先正向生成这个序列,然后调用reversed()函数
|
1
2
|
>>> for i in reversed(range(1, 10, 2)):
... print(i) |
按顺序遍历一个序列,可以使用sorted()函数。该函数返回一个新的排序列表,同时保证源列表不变。
|
1
2
3
|
>>> basket = [\'apple\', \'orange\', \'apple\', \'pear\', \'orange\', \'banana\']
>>> for f in sorted(set(basket)):
... print(f) |
若要在循环内部修改正在遍历的序列(例如复制某些元素),一般先制作副本。在序列上循环不会隐式地创建副本。切片表示法使这尤为方便。
|
1
2
3
4
|
>>> words = [\'cat\', \'window\', \'defenestrate\']
>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
|
深入条件控制
|
1
2
3
4
5
6
7
8
9
10
|
while 和 if 语句中使用的条件可以包含任意的操作,而不仅仅是比较。
比较操作符 in 和 not in 检查一个值是否在一个序列中出现(不出现)。is 和 is not 比较两个对象是否为同一对象;这只和列表这样的可变对象有关。所有比较运算符都具有相同的优先级,低于所有数值运算符。
可以级联比较。例如, a < b == c 测试 a 是否小于 b 并且 b 等于 c。
可将布尔运算符 and 和 or 用于比较,比较的结果(或任何其他的布尔表达式)可以用 not取反。这些操作符的优先级又低于比较操作符;它们之间,not 优先级最高,or 优先级最低,所以 A and not B or C 等效于 (A and (not B)) or C。与往常一样,可以使用括号来表示所需的组合。
布尔运算符 and 和 or 是所谓的 短路 运算符:依参数从左向右求值,结果一旦确定就停止。例如,如果 A 和 C 都为真,但 B 是假, A and B and C 将不计算表达式 C。用作一个普通值而非逻辑值时,短路操作符的返回值通常是最后一个计算的。可以把比较或其它逻辑表达式的返回值赋给一个变量。例如,
>>> string1, string2, string3 = \'\', \'Trondheim\', \'Hammer Dance\'
>>> non_null = string1 or string2 or string3
>>> non_null\'Trondheim\'注意 Python 与 C 不同,在表达式内部不能赋值。C 程序员可能会抱怨这一点,但它避免了一类 C 程序中常见的问题: 在表达式中输入 = 而真正的意图是== 。
|