Python-可迭代对象、迭代器与生成器

0 前言

>>返回Python系列文章目录<<

1 可迭代对象 Iterable

在Python中,如果一个对象具有多个成员,并且可以每次返回一个成员,则被称为可迭代对象Iterable

可迭代对象包括以下几类:

  • 迭代器(Iterator):可依次返回成员
    • 生成器(generator):一种函数方式构建的特殊迭代器
  • 集合类型:无法索引成员,只能按默认顺序返回,如set
    • 映射类型:可以依据键值索引成员,如dict
      • 序列(Sequence),可以按index索引成员,如listtuplestr
  • 文件对象:file

可迭代对象的本质是实现了__iter__()方法

  • 在Python中,一个对象是否是可迭代对象取决于是否实现了__iter__()_getitem_()方法,任何具有_iter_()_getitem_()方法的对象,Python就认为它是一个Iterable,包括自定义对象

可迭代对象都能使用in关键字

在Python中,所有可迭代对象都能使用in关键字提取成员

  1. 可以使用in关键字遍历
for num in range(10)
    # code
  1. 可以使用in关键字判断
if(5 in range(10)):     # True
    # code
  1. 字典的可迭代成员是它的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 生成器表达式

  1. 通过迭代能在range()基础上生成更复杂的生成器
g = (x * x for x in range(10))
for n in g:
    print(n)

  1. 生成器可使用 if筛选
g = (x * x for x in range(10) if x%2 == 0)

  1. 生成器可以两层迭代
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()方法获取长度

listtuplestr等都是序列,但是集合set不是序列

生成器记录列表的生成规律,但不创建和保存完整的列表,从而节省大量的空间。

6.1 列表生成式

生成器可以随时转为列表


  1. 对已有的生成器,使用list()方法:
g = list(range(10))

  1. 生成生成器过程中,将最外()换成[ ]可直接得到列表:
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

>>返回Python系列文章目录<<

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值