循环迭代的速度讨论:
for使用的是C程序代码编写的,
while使用的是python虚拟机运行python字码节的
可迭代对象:
如果对象是实际保存的序列,或者在可迭代工具环境中(如for循环,下面的next())一次产生一个结果对象,就可看作是可迭代的。包括实际序列(如,列表,元组,字符串),以及按需求而计算的虚拟序列(如,字典,文件)
文件的迭代:
>>> f = open('data.txt')
>>> i = iter(f) # f自身就是一个iter内置函数对象(可迭代对象),下一行代码即是验证
>>> i == f
True
>>> f.__next__()
'1\n'
>>> f.__next__()
'2\n'
>>> f.__next__()
'3\n'
>>> f.__next__()
'abd\n'
>>> f.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> dir(f) # 查看f的所有方法和属性
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines']
>>>
>>>
>>> for j in open('data.txt'): # 使用for循环,可以避免提取完文件后报错
... print(j,end='')
...
1
2
3
abd
>>>
>>> f = open('data.txt')
>>> next(f) # next()的使用,会自动调用对象的__next__方法
'1\n'
>>> next(f)
'2\n'
>>> next(f)
'3\n'
>>> next(f)
'abd\n'
>>> next(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
>>> help(next) # 深入理解next()
Help on built-in function next in module builtins:
next(...)
next(iterator[, default])
Return the next item from the iterator. If default is given and the iterator
is exhausted, it is returned instead of raising StopIteration.
>>>
对iter的使用,将列表/元组/字符串转化为可迭代对象
>>> s = 'abcd'
>>> i = iter(s) # 字符串本身不是可迭代对象
>>> i == s
False
>>> next(i)
'a'
>>> next(i)
'b'
>>>
对iter的使用,将字典转化为可迭代对象,仅转化其key值
>>> d = {'a':1,'b':2,'c':3}
>>> i = iter(d) # 字典本身不是可迭代对象
>>> i == d
False
>>> next(i)
'a'
>>> next(i)
'b'
>>>
>>> help(iter) # 深入理解iter()
Help on built-in function iter in module builtins:
iter(...)
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
>>>
程序优化之使用列表解析器
>>> l = [1,2,3,4]
>>> t = [i**2 for i in l] # 列表解析器是使用C程序代码编程,执行效率更高
>>> t
[1, 4, 9, 16]
>>>
>>> lines = [line for line in open('data.txt')] # 可以这样读取文件,效率较高
>>> lines
['1\n', '2\n', '3\n', 'abd\n']
>>>
列表解析器的扩展
>>> [x+y for x in 'abc' for y in '123'] # 多重循环
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
>>> a = [1,2,3,4,5]
>>> [i for i in a if i//2==0] # 增加判断
[1]
>>> [i for i in a if i/2==0]
[]
>>> [i for i in a if i%2==0]
[2, 4]
>>>
其他内置函数对可迭代对象得支持
>>> l
[1, 2, 3, 4]
>>> max(l)
4
>>> min(l)
1
>>> sum(l)
10
>>> all(l)
True
>>> any(l)
True
>>>
>>> '&'.join(open('data.txt'))
'1\n&2\n&3\n&abd\n'
>>> a,*b = open('data.txt')
>>> a,b
('1\n', ['2\n', '3\n', 'abd\n'])
>>>
多迭代器与单迭代器
>>> r = range(5) # range支持相同结果的多个活跃迭代器
>>> r
range(0, 5)
>>> i1 = iter(r)
>>> next(i1)
0
>>> next(i1)
1
>>> i2 = iter(r)
>>> next(i2)
0
>>> m = map(abs,(-1,1,22,-12)) # 与range不同,zip/mapfilter不支持相同结果的多个活跃迭代器
>>> m
<map object at 0x0000020CE8081DA0>
>>> i3 = iter(m)
>>> next(i3)
1
>>> i4 = iter(m)
>>> next(i4)
1
>>> next(i4)
22
>>> next(i3)
12
>>>