上一篇 ( 罗列 Python 标准库中的生成器函数 (1) ) 我们列举了 用于过滤的生成器函数 和 用于映射的生成器函数,接下来我们继续列举标准库中剩下的生成器函数
接下来这一组是用于合并的生成器函数,这些函数都从输入的多个可迭代对象中产出元素。chain 和 chain.from_iterable 按顺序(一个接一个)处理输入的可迭代对象,而 product、zip 和 zip_longest 并行处理输入的各个可迭代对象。如下所示。
3、用于合并多个可迭代对象的生成器函数
模块 | 函数 | 说明 |
---|---|---|
itertools | chain(it1, ..., itN) | 先产出 it1 中的所有元素,然后产出 it2 中的所有元素,以此类推,无缝连接在一起 |
itertools | chain.from_iterable(it) | 产出 it 生成的各个可迭代对象中的元素,一个接一个,无缝连接在一起;it 应该产出可迭代的元素,例如可迭代的对象列表 |
itertools | product(it1, ..., itN,repeat=1) | 计算笛卡儿积:从输入的各个可迭代对象中获取元素,合并成由 N 个元素组成的元组,与嵌套的 for 循环效果一样;repeat 指明重复处理多少次输入的可迭代对象 |
(内置) | zip(it1, ..., itN) | 并行从输入的各个可迭代对象中获取元素,产出由 N 个元素组成的元组,只要有一个可迭代的对象到头了,就默默地停止 |
itertools | zip_longest(it1, ...,itN, fillvalue=None) | 并行从输入的各个可迭代对象中获取元素,产出由 N 个元素组成的元组,等到最长的可迭代对象到头后才停止,空缺的值使用 fillvalue填充 |
接下来我们先展示 itertools.chain 和 zip 生成器函数及其同胞的用法:
>>> list(itertools.chain('ABC', range(2))) # 1
['A', 'B', 'C', 0, 1]
>>> list(itertools.chain(enumerate('ABC'))) # 2
[(0, 'A'), (1, 'B'), (2, 'C')]
>>> list(itertools.chain.from_iterable(enumerate('ABC'))) # 3
[0, 'A', 1, 'B', 2, 'C']
>>> list(zip('ABC', range(5))) # 4
[('A', 0), ('B', 1), ('C', 2)]
>>> list(zip('ABC', range(5), [10, 20, 30, 40])) # 5
[('A', 0, 10), ('B', 1, 20), ('C', 2, 30)]
>>> list(itertools.zip_longest('ABC', range(5))) # 6
[('A', 0), ('B', 1), ('C', 2), (None, 3), (None, 4)]
>>> list(itertools.zip_longest('ABC', range(5), fillvalue='?')) # 7
[('A', 0), ('B', 1), ('C', 2), ('?', 3), ('?', 4)]
1、调用 chain 函数时通常传入两个或更多个可迭代对象。
2、如果只传入一个可迭代的对象,那么 chain 函数没什么用。
3、但是 chain.from_iterable 函数从可迭代的对象中获取每个元素,
然后按顺序把元素连接起来,前提是各个元素本身也是可迭代的对象。
4、zip 常用于把两个可迭代的对组。
5、zip 可以并行处理任意数量个的对象到头了,生成器就停。
6、itertools.zip_longest 函数的作用与 zip 类似,不过输入的所有
可迭代对象都会处理到头,如果需要会填充 None。
7、fillvalue 关键字参数用于指定填充的值。
继续演示 itertools.product 生成器函数:
>>> list(itertools.product('ABC', range(2))) # 1
[('A', 0), ('A', 1), ('B', 0), ('B', 1), ('C', 0), ('C', 1)]
>>> suits = 'spades hearts diamonds clubs'.split()
>>> list(itertools.product('AK', suits)) # 2
[('A', 'spades'), ('A', 'hearts'), ('A', 'diamonds'), ('A', 'clubs'),
('K', 'spades'), ('K', 'hearts'), ('K', 'diamonds'), ('K', 'clubs')]
>>> list(itertools.product('ABC')) # 3
[('A',), ('B',), ('C',)]
>>> list(itertools.product('ABC', repeat=2)) # 4
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'),
('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')]
>>> list(itertools.product(range(2), repeat=3))
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0),
(1, 0, 1), (1, 1, 0), (1, 1, 1)]
>>> rows = itertools.product('AB', range(2), repeat=2)
>>> for row in rows: print(row)
...
('A', 0, 'A', 0)
('A', 0, 'A', 1)
('A', 0, 'B', 0)
('A', 0, 'B', 1)
('A', 1, 'A', 0)
('A', 1, 'A', 1)
('A', 1, 'B', 0)
('A', 1, 'B', 1)
('B', 0, 'A', 0)
('B', 0, 'A', 1)
('B', 0, 'B', 0)
('B', 0, 'B', 1)
('B', 1, 'A', 0)
('B', 1, 'A', 1)
('B', 1, 'B', 0)
('B', 1, 'B', 1)
1、三个字符的字符串与两个整数的值域得到的笛卡儿积是六个元组(因为 3 * 2 等于 6)。
2、两张牌('AK')与四种花色得到的笛卡儿积是八个元组。
3、如果传入一个可迭代的对象,product 函数产出的是一系列只有一
个元素的元组,不是特别有用。
4、repeat=N 关键字参数告诉 product 函数重复 N 次处理输入的各个
可迭代对象。
网友评论