8.1 if 语句
8.11 迭代器和iter()函数
根本上说,迭代器就是有一个next()方法的对象,而不是通过索引来计数。当你或者一个循环机制需要下一个项时,调用迭代器的next()方法就可以获得它。条目全部取出后,会引发一个StopIteration异常。
不过,迭代器也有一些限制。不能向后移动,不能回到开始,也不能复制一个迭代器。若需要再次或者同时迭代同个对象,你只能创建另一个迭代器对象。
reversed()内建函数将返回一个反序访问的迭代器。any() all() 两个内建函数返回如果迭代器中某个/ 所有条目为真,则返回真。
使用迭代器
>>> tuple1 = ('x', 'y', 'z')
>>> i = iter(tuple1)
>>> i.next()
'x'
>>> i.next()
'y'
>>> i.next()
'z'
>>> i.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> legends = { ('Poe', 'author'): (1809, 1849, 1976), ('Gaudi', 'architect'): (1852, 1906, 1
... 987), ('Freud', 'psychanalyst'): (1856, 1939, 1990) }
>>> for eachLegend in legends:
... print 'Name: %s\tOccupation: %s' % eachLegend
... print ' Birth: %s\tDeath: %s\tAlbum: %s\n' % legends[eachLegend]
Name: Poe Occupation: author
Birth: 1809 Death: 1849 Album: 1976
Name: Freud Occupation: psychanalyst
Birth: 1856 Death: 1939 Album: 1990
Name: Gaudi Occupation: architect
Birth: 1852 Death: 1906 Album: 1987
另外,python还引进了三个新的内建字典方法来定义迭代。 dict.iterkeys() dict.itervalues() dict.iteritems()
文件对象生成的迭代器会自动调用readline()方法。这样,循环就可以访问文本文件的所有行。
>>> f = open('/root/mypython/5-4.py')
>>> for line in f:
... print line
#!/usr/bin/python
# -*- coding:utf-8 -*-
year = int(raw_input('Please input a year: '))
if year%4==0 and year%100!=0:
print '1'
elif year % 4 == 0 and year % 400 == 0:
print '1'
else:
print '0'
8.11.5 可变对象和迭代器
一个序列的迭代器只是记录你当前到达第多少个元素,所以如果在迭代时改变了元素,更新会立即反应到所迭代的条目上。
在迭代字典的键时,绝对不能改变这个字典。使用字典的keys()方法是可以的,因为keys()方法返回一个独立于字典的列表。而迭代器是于实际对象绑定在一起的。
>>> d1 = { 'a': 1, 'b': 2, 'c': 3 }
>>> for eachKey in d1:
... print eachKey, d1[eachKey]
... del d1[eachKey]
a 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
dictionary changed size during iteration
iter(obj)
iter(func, sentinel)
若传递一个参数给iter(),它会判断是否参数是一个序列,若是,根据索引从0 一直迭代到序列结束。另一个创建迭代器的方法是使用类,一个实现了 __iter__() 和 next()方法的类可以作为迭代器使用。
若传递两个参数,会重复调用func, 知道迭代器的下个值为sentinel。
8.12 列表解析
[ expr for iter_var in iterable ]
>>> [ x ** 2 for x in range(6) ]
[0, 1, 4, 9, 16, 25]
[ expr for iter_var in iterable if cond_expr ]
>>> [ x for x in range(20) if x % 2 ]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
矩阵
>>> [ (x+1, y+1) for x in range(3) for y in range(5) ]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)]
8.13 生成器表达式
生成器是一个特定的函数,允许返回一个值,然后“暂停”代码的执行,稍后恢复。
列表解析的一个不足就是必须要生成所有的数据,用以创建整个列表。
( expr for iter_var in iterable if cond_expr )
sum(len(word) for line in data for word in line.split() )
交叉配对样例
>>> rows = [1, 2, 3, 17]
>>> def cols():
... yield 56
... yield 2
... yield 1
>>> pairs = ((i, j) for i in rows for j in cols())
>>> for eachPairs in pairs:
... print eachPairs
(1, 2)
(1, 1)
(2, 56)
(2, 2)
(2, 1)
(3, 56)
(3, 2)
(3, 1)
(17, 56)
(17, 2)
(17, 1)