Python的for循环语法上跟C语言差别较大,刚接触时我也很不适应,现在却觉得Python的for循环可读性非常好。迭代,就是在循环中遍历对象的所有元素,迭代的过程不一定都是for循环,while等其它循环方式也是在做迭代。
Python内置了的很多可迭代的数据对象,比如List,Dict,String,Tuple,Set等等。所谓可迭代对象(Iterable),简单说,就是可以直接在Python的for循环中遍历的对象。
下面的示例代码,将Python内置的各种常用可迭代对象,都做了一次遍历:
>>> a = [1,2,3,4,5] # list
>>> for n in a: print(n)
...
1
2
3
4
5
>>> b = 'abcde' # string
>>> for c in b: print(c)
...
a
b
c
d
e
>>> c = (1,2,3,4,5) # tuple
>>> for n in c: print(n)
...
1
2
3
4
5
>>> d = {'a':1,'b':2,'c':3} # dict
>>> for x in d: print(x)
...
a
b
c
>>> for k,v in d.items(): print(k,v)
...
a 1
b 2
c 3
>>> e = {1,2,3,4} # set
>>> for i in e: print(i)
...
1
2
3
4
我们可以使用collections模块的Iterable对象来判断,某个对象是否是可迭代的。
>>> from collections.abc import Iterable
>>> isinstance('abcd', Iterable)
True
>>> isinstance((1,2,3,4), Iterable)
True
>>> isinstance(1234, Iterable)
False
>>> isinstance({}, Iterable)
True
可迭代对象不等于迭代器!但是,迭代器是一定是可迭代对象。Iterables are not equal to Iterators, but Iterators are all Iterables. 迭代器和可迭代对象的一个重要区别,就是能否用Python内置的next函数调用。迭代器可以,仅仅是可迭代对象不行。
>>> a = [1,2,3,4]
>>> next(a)
Traceback (most recent call last):
File "", line 1, in
TypeError: 'list' object is not an iterator
>>> a = iter(a)
>>> next(a)
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
4
>>> next(a)
Traceback (most recent call last):
File "", line 1, in StopIteration
a作为List对象,只是可迭代对象,不是迭代器,不能被next函数调用。用内置函数iter将a变为迭代器后,就可以使用next函数,一个一个将内部的数据释放出来使用,知道最后抛出StopIteration异常。
可迭代对象在遍历的时候,也是很方便的,为什么还要搞出一个迭代器出来?
我觉得是因为内存!
可迭代对象所有的数据都存放在内存中,而迭代器不全是这样。如果是生成器(generator,它也属于迭代器),在迭代过程中,数据一个个的释放出来,不会存在数据一次性释放出来而占用大量内存的情况。如果是可迭代对象转换而成的迭代器,每一个数据被释放出来后,对应的内存就消失,即只能next,而没有回头路可走。因此,迭代器在内存占用方面更友好。
下面用zip函数返回的迭代器来举例:
>>> zipped = zip('1234','abcd')
>>> list(zipped)
[('1', 'a'), ('2', 'b'), ('3', 'c'), ('4', 'd')]
>>> list(zipped)
[] # data is gone for 2nd use
>>> zipped = zip('1234','abcd')
>>> next(zipped)
('1', 'a')
>>> next(zipped)
('2', 'b')
>>> next(zipped)
('3', 'c')
>>> next(zipped)
('4', 'd')
>>> next(zipped)
Traceback (most recent call last):
File "", line 1, in
StopIteration
>>> list(zipped)
[] # no data at all
而如果只是一个可迭代对象,是可以反复迭代,数据不会被清除:
>>> a = [1,2,3,4]
>>> for i in a: print(i)
...
1
2
3
4
>>> for i in a: print(i)
...
1
2
3
4
>>> a
[1, 2, 3, 4]
这就是区别!最后说一下,迭代器可以使用next函数,迭代器也可以在for循环中迭代。
>>> zipped = zip('1234','abcd')
>>> for i in zipped:
... print(i)
...
('1', 'a')
('2', 'b')
('3', 'c')
('4', 'd')
>>> for i in zipped:
... print(i)
...
循环一次后,数据消失!
以上就是对Python中的可迭代对象(Iterable)和迭代器(Iterator)的介绍。
-- EOF --