Python 函数创建迭代器以实现高效循环
与大多数编程语言一样,Python 提供 while 和 for 语句来构成循环结构。for 语句特别适用于遍历可迭代对象,例如列表、元组或字符串。Python 标准库中的 itertools 模块定义了更有效和快速的迭代工具。这些迭代器构建块是类似 Haskell 和 SML 等函数式编程语言中类似工具的 Python 风格实现。
itertools 模块中的函数分为三种类型。
- 无限迭代器
- 有限迭代器
- 组合迭代器
以下函数生成无限序列。
count() − 此函数返回从起始值开始的等间距值的迭代器。该函数可以具有可选的步长值,以该间隔递增后续值。
>>> from itertools import count >>> for x in count(20): print (x) >>> for x in count(100,10): print (x)
第一个语句将生成从 20 开始的无限序列,第二个语句将生成从 100 开始,步长为 10 的数字。请注意,这些循环是无限的,不会自行终止。它们将在按下 Ctrl-C 时终止。
cycle() − 此函数开始返回给定可迭代对象中的每个元素并保存其副本。一旦元素耗尽,就会返回保存的副本中的元素,从而形成无限循环。
>>> from itertools import cycle >>> for x in cycle("hello"): print (x)
字符串中的字符将重复打印,直到发出键盘中断 Ctrl-C。
repeat() − 此函数重复返回对象参数。如果提供了第二个参数“times”,则重复该次数。
>>> from itertools import repeat >>> for x in repeat(1): print (x) >>> for x in repeat('hello', 10): print (x)
第一个循环将无限打印 1。第二个循环打印“hello”10 次。
以下类别中的函数返回在最短输入序列上终止的有限迭代器。
accumulate() − 此函数有两个参数。第一个是可迭代对象(列表、元组或字符串)。第二个参数默认为 operator.add()(operator 模块中实现标准加法运算符的函数),但可以是任何其他接收两个数字参数的函数。
accumulate(sequence, func)
输入序列的前两个元素由 func 处理。处理结果是下一次迭代的第一个参数,而 func 的第二个参数是输入序列中的第三个元素。此过程重复,直到序列耗尽。accumulate 函数返回一个迭代器,其中每个元素都是处理连续元素的累积结果。
在以下示例中,列表中的数字被累加。请注意,默认函数参数是加法运算。
>>> from itertools import accumulate >>> list(accumulate([1,2,3,4,5])) [1, 3, 6, 10, 15]
我们可以将用户定义的函数作为 accumulate() 函数的第二个参数。
>>> def multiply(x,y): return x*y >>> list(accumulate([1,2,3,4,5], multiply)) [1, 2, 6, 24, 120]
此行为有点类似于内置的 reduce() 函数。reduce() 函数仅返回累积的最终结果,而 accumulate() 构建所有中间结果的迭代器。
chain() − 此函数可以有多个可迭代对象作为参数。它将第一个可迭代对象的每个元素生成到结果迭代器中,并继续进行下一个,直到可迭代对象参数耗尽。
>>> from itertools import chain >>> list(chain([10,20],'hello',range(4))) [10, 20, 'h', 'e', 'l', 'l', 'o', 0, 1, 2, 3]
dropwhile() − 此函数通过丢弃可迭代对象的元素返回一个迭代器,只要谓词函数参数返回 true。一旦函数返回 false,所有剩余的元素都将生成到迭代器中。
>>> from itertools import dropwhile >>> def iseven(x): if x % 2 == 0: return True else: return False >>> list(dropwhile(iseven, [12,90,61,4,15])) [61, 4, 15]
filterfalse() − 此函数通过过滤掉谓词函数结果为 False 的元素返回一个迭代器。
>>> from itertools import filterfalse >>> def iseven(x): if x % 2 == 0: return True else: return False >>> list(filterfalse(iseven, [12,90,61,4,15])) [61, 15]
islice() − 此函数通过从可迭代对象中选择某些元素来构建迭代器。选择标准取决于 start、stop 和 step 参数。选择从 start 值开始,一直持续到 stop 值。如果 stop 为 None,则一直到可迭代对象的末尾,否则选择在指定的索引处停止。step 参数默认为 1。元素的选择按 step 参数递增。所有参数都不能为负数。
>>> from itertools import islice >>> list(islice(range(10),1,5,2)) [1, 3] >>> list(islice(range(10),0,None,3)) [0, 3, 6, 9] >>> list(islice(range(10),5,None)) [5, 6, 7, 8, 9] >>> list(islice(range(10),5)) [0, 1, 2, 3, 4]
以下函数从可迭代对象生成组合迭代器。
product() − 此函数生成一个迭代器,它是输入序列中元素的笛卡尔积。这相当于构建嵌套的 for 循环,每个循环遍历一个可迭代序列。
在以下示例中,列表推导式技术用于对两个序列运行两个嵌套循环以构建笛卡尔积。
>>> [[x,y] for x in [1,2,3] for y in ['a','b','c']] [[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c'], [3, 'a'], [3, 'b'], [3, 'c']]
product() 函数产生类似的结果。
>>> from itertools import product >>> list(product([1,2,3],['a','b','c'])) [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]
permutations() − 此函数生成输入可迭代对象中元素的所有可能的排列。每个排列的长度可以作为此函数的第二个参数指定。如果未指定,则长度为 1。
>>> list(permutations(range(1,4),2)) [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
combinations() − 此函数生成输入可迭代对象中元素的所有可能的组合。每个排列的长度可以作为此函数的第二个参数指定。如果未指定,则长度为 1。
>>> from itertools import combinations >>> list(combinations(range(1,4),2)) [(1, 2), (1, 3), (2, 3)]
本文介绍了 Python 库的 itertools 模块中定义的各种迭代器工具。