Python-可迭代对象
0 前言
1 可迭代对象 Iterable
在Python中,如果一个对象具有多个成员,并且可以每次返回一个成员,则被称为可迭代对象(Iterable
)
可迭代对象包括以下几类:
- 迭代器(Iterator):可依次返回成员
- 生成器(generator):一种函数方式构建的特殊迭代器
- 集合类型:无法索引成员,只能按默认顺序返回,如
set
- 映射类型:可以依据键值索引成员,如
dict
- 序列(Sequence),可以按index索引成员,如
list
、tuple
、str
等
- 序列(Sequence),可以按index索引成员,如
- 映射类型:可以依据键值索引成员,如
- 文件对象:file
① 可迭代对象的本质是实现了__iter__()方法
- 在Python中,一个对象是否是可迭代对象取决于是否实现了
__iter__()
或_getitem_()
方法,任何具有_iter_()
或_getitem_()
方法的对象,Python就认为它是一个Iterable,包括自定义对象
② 可迭代对象都能使用in关键字
在Python中,所有可迭代对象都能使用in
关键字提取成员
- 可以使用
in
关键字遍历
for num in range(10)
# code
- 可以使用
in
关键字判断
if(5 in range(10)): # True
# code
- 字典的可迭代成员是它的
keys
a = {'a': 1, 'b':2}
print('a' in a)
# True
2 迭代器 Iterator
迭代器(Iterator)是一个表示数据流的对象,可通过重复调用__next__()
(或使用内置函数next()
)方法来获取元素。当没有元素存在时,抛出StopIteration
异常
任意可迭代对象使用iter()
方法的返回值是一个迭代器(Iterator)
① 迭代器的本质是实现了__next__()方法
迭代器都具有__next__()
方法,迭代器的初值是一个iterator类,使用__next__()
方法或next()
函数后一次返回可迭代对象的一个成员,当最后一个成员返回后,报StopIteration
错误
迭代器自身也具有__iter__()
方法,所以迭代器也是可迭代对象。特殊的是,iter(Iterator)
返回的是迭代器本身
迭代器(Iterator)是一次性的,不可逆
var_dict = {'a': 1, 'b':2}
var_iter = iter(var_dict)
print(var_iter) # <dict_keyiterator object at 0x7fd9e93d2450>
print(next(var_iter)) # 'a'
print(next(var_iter)) # 'b'
print(next(var_iter)) # StopIteration
2.1 打包 zip()得到迭代器
zip()
将多个迭代器的相同位置元素组成元组,形成新的迭代器
x = range(3)
y = 'abc'
print(next(zip(x, y)))
# (0, 'a')
与两层迭代对比:
x = [a+b for a in 'ABC' for b in '123'] # 两层迭代
y = [a+b for a, b in zip('ABC', '123')] # 打包迭代
>>>x = ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
>>>y = ['A1', 'B2', 'C3']
3 生成器 generator
生成器(generator
)是一种特殊的迭代器,可以由3种类型:
- 有
yield
关键字的函数 range()
函数- 生成器表达式
3.1 有yield
关键字的函数
def my_generator():
for i in [0, 1, 2]:
yield i
print('i=%s' %(i))
g = my_generator()
print(next(g)) # 0 i=0
print(next(g)) # 1 i=1
print(next(g)) # 2
有yield
的函数被next()
函数调用时执行一次,到yield
语句后停止,将yield
的对象返回,类似于return
当下次被next()
函数调用时,从上一次yield
语句处继续执行,而不是从头开始执行
3.2 range()函数
range()
是最简单的生成器:
range(start,end,step) # 包括start,不包括end
range(start,end) # step默认为1
range(end) # start默认为0
3.3 生成器表达式
- 通过迭代能在
range()
基础上生成更复杂的生成器
g = (x * x for x in range(10))
for n in g:
print(n)
- 生成器可使用
if
筛选
g = (x * x for x in range(10) if x%2 == 0)
- 生成器可以两层迭代
g = (m+n for m in 'ABC' for n in '123')
4 集合类型
集合set
也是一种可迭代对象,可以使用in
关键字,但是无法索引成员
使用in
关键字时,集合按照升序依次返回成员
x = {10, 30, 20}
for i in x:
print(i)
#10
#20
#30
5 映射类型
字典dict
也是一种可迭代对象,可以使用in
关键字,也可以使用key
进行成员索引
字典dict
使用in关键字时,字典被视为由键值key
按顺序组成的序列
x = {'a':10, 'c':30, 'b':20}
for i in x:
print(i)
# a
# c
# b
6 序列Sequence
同时满足以下条件的可迭代对象称为序列:
- 支持下标访问,即实现了
__getitem__()
方法 - 同时定义了
__len__()
方法,可通过len()
方法获取长度
如list
、tuple
、str
等都是序列,但是集合set
不是序列
生成器记录列表的生成规律,但不创建和保存完整的列表,从而节省大量的空间。
6.1 列表生成式
生成器可以随时转为列表
- 对已有的生成器,使用
list()
方法:
g = list(range(10))
- 生成生成器过程中,将最外
()
换成[ ]
可直接得到列表:
g = [x for x in range(10)]
6.2 枚举 enumerate()
enumerate()函数将序列对象的下标和元素对应打包
for index, value in enumerate('ABC'):
print index, value
>>>0 A
>>>1 B
>>>2 C