·  阅读 442

# 1 无限迭代器 infinite iterators

## count

``````count(10)  # 10 11 12 13 ...
count(10, 0.5)  # 10 10.5 11 11.5 ...
# 注：浮点数计数时，通过下面的方法可以获得更好的准确性
(10 + 0.5 * i for i in count())  # 10.0 10.5 11 11.5 ...
map(lambda x: 2 * x**2 + 1, count())  #  1 3 9 19 33 51 ...
zip(count(), ['a', 'b', 'c'])  # [(0, 'a'), (1, 'b'), (2, 'c')]

## cycle

``````cycle(['a','b','c'])  # a b c a b c a ...
cycle(range(3))  # 0 1 2 0 1 2 0 ...

## repeat

``````repeat('abc')  # abc abc abc ...
repeat(range(3))  # range(0, 3) range(0, 3) range(0, 3) ...
repeat(1, 3)  # 1 1 1
map(pow, range(5), repeat(2))  # 0 1 4 9 16
zip(repeat('num'), [1,2,3])  # [('num', 1), ('num', 2), ('num', 3)]

# 2 有限迭代器 Iterators terminating on the shortest input sequence

## accumulate

【Python 3.8 更改：添加了可选的 initial 形参】

``````accumulate([1,2,3,4,5])  # 1 3 6 10 15
accumulate([1,2,3,4,5], operator.mul)  # 1 2 6 24 120
accumulate([1,2,3,4,5], min)  # 1 1 1 1 1
accumulate([1,2,3,4,5], max)  # 1 2 3 4 5
accumulate([2,4,5,8,10], lambda x, _: 1/x)  # 2 0.5 2.0 0.5 2.0
accumulate([2,4,5,8,10], lambda _, x: 1/x)  # 2 0.25 0.2 0.125 0.1
accumulate([2,4,5,8,10], lambda x, y: x*y)  # 2 8 40 320 3200
# 注：functools.reduce() 只获得最终累积值
reduce(lambda x, y: x*y, [2,4,5,8,10])  # 3200
accumulate([1,2,3,4,5], initial=100)  # 100 101 103 106 110 115

## chain

``````chain([1,2], [3,4], [5])  # 1 2 3 4 5
chain([[1,2], [3,4], [5]])  # [[1, 2], [3, 4], [5]]
chain(*[[1,2], [3,4], [5]])  # 1 2 3 4 5
chain(['ABC', 'DEF'])  # ABC DEF
chain(*['ABC', 'DEF'])  # A B C D E F

## chain.from_iterable

``````chain.from_iterable([1,2], [3,4], [5])  # Error
chain.from_iterable([[1,2], [3,4], [5]])  # 1 2 3 4 5
chain.from_iterable(*[[1,2], [3,4], [5]])  # Error
chain.from_iterable(['ABC', 'DEF'])  # A B C D E F
chain.from_iterable(*['ABC', 'DEF'])  # Error

## compress

``````compress('ABCDEF', [1,0,1,0,1,1])  # A C E F
compress('ABCDEF', [1])  # A
compress('ABCDEF', [True, -1, 1, 0.5, 'C', [1]])  # A B C D E F
compress('ABCDEF', [False, 0, 0.0, '', [], None])  # (Empty)
# 注：布尔值为False的包括 [0, -0, 0.0, 0j, [], (), {}, None, ""] 等

## dropwhile

``````dropwhile(lambda x: x<3, [1,2,3,4,5])  # 3 4 5
dropwhile(lambda line: line.startswith('#'), f)  # 读取文件时过滤文件首部以#开头的行

## filterfalse

``````filterfalse(lambda x: x%2, range(10))  # 0 2 4 6 8
filterfalse(None, range(10))  # 0
# 注：filter() 返回 iterable 中 predicate 为 True 的元素
filter(lambda x: x%2, range(10))  # 1 3 5 7 9
filter(None, range(10))  # 1 2 3 4 5 6 7 8 9

## groupby

``````# 注：实际返回结果中value为迭代器
groupby('AABB')  # {'A': ['A', 'A'], 'B': ['B', 'B']}
groupby('AaBb', key=lambda x: x.upper())  # {'A': ['A', 'a'], 'B': ['B', 'b']}
div_size = lambda x: 'small' if x < 3 else 'medium' if x == 3 else 'big'
groupby([1,2,3,4,5], key=div_size)  # {'small': [1, 2], 'medium': [3], 'big': [4, 5]}

## islice

``````islice('ABCDEFG', 2)  # A B
islice('ABCDEFG', 2, 5)  # C D E
islice('ABCDEFG', 2, None)  # C D E F G
islice('ABCDEFG', 2, 5, 2)  # C E
islice('ABCDEFG', 2, None, 2)  # C E G
# 注：如果 start 为 None，迭代从0开始。如果 step 为 None ，步长缺省为1。
islice('ABCDEFG', None, None)  # A B C D E F G

## pairwise

【Python 3.10 新特性】

``````# 注：输出迭代器中 2-tuples 的数量将比输入的数量少一个。
pairwise('ABCDEFG')  # AB BC CD DE EF FG
# 注：如果输入的可迭代对象小于两个值，则该值为空。
pairwise('A')  # (Empty)

## takewhile

``````takewhile(lambda x: x<5, [1,2,3,4,5])  # 1 2
takewhile(lambda x: x.isdigit(), '123abc456')  # 1 2 3

## tee

``````# 注：实际返回结果为迭代器
tee(range(3))  # [0, 1, 2] [0, 1, 2]

## zip_longest

``````zip_longest('ABCD', 'xy')  # ('A','x') ('B','y'), ('C',None) ('D',None)
zip_longest('ABCD', 'xy', fillvalue='-')  # ('A','x') ('B','y'), ('C','-') ('D','-')

# 3 组合迭代器 Combinatoric iterators

## product

``````product('AB', range(3))  # ('A',0) ('A',1) ('A',2) ('B',0) ('B',1) ('B',2)
product(range(2), repeat=3)  # (0,0) (0,1) (1,0) (1,1)

## permutations

``````permutations(range(3))  # (0,1,2) (0,2,1) (1,0,2) (1,2,0) (2,0,1) (2,1,0)
permutations('ABC')  # ('A','B','C') ('A','C','B') ('B','A','C') ('B','C','A') ('C','A','B') ('C','B','A')
permutations('ABC', 2)  # ('A','B') ('A','C') ('B','A') ('B','C') ('C','A') ('C','B')

## combinations

``````combinations(range(3), 2)  # (0,1) (0,2) (1,2)
combinations('ABC', 3)  # ('A','B','C')
combinations('ABC', 2)  # ('A','B') ('A','C') ('B','C')

## combinations_with_replacement

``````# 注：combinations 相当于不可放回，combinations_with_replacement 相当于可放回
combinations_with_replacement(range(3), 2)  # (0,0) (0,1) (0,2) (1,1) (1,2) (2,2)
combinations_with_replacement('ABC', 2)  # ('A','A') ('A','B') ('A','C') ('B','B') ('B','C') ('C','C')

# 4 itertools 配方 Recipes

itertools 配方使用现有的 itertools 作为基础构件来创建扩展的工具集。

``````pip install more-itertools