>>> from env_helper import info; info()
页面更新时间: 2024-04-05 08:24:56
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
11.4. 使用迭代器相关模块¶
11.4.1. itertools 模块¶
itertools 模块包含很多常用的迭代器以及用来组合迭代器的函数。 这个模块实现一系列 iterator ,这些迭代器受到APL,Haskell和SML的启发里的函数大致可以分为几类:
已有的迭代器创建新的迭代器的函数。
接受迭代器元素作为参数的函数。
选取部分迭代器输出的函数。
给迭代器输出分组的函数。
创建新的迭代器¶
itertools.count(start, step)
¶
itertools.count(start, step)
返回一个等分的无限数据流。
初始值默认为0,间隔默认为1,创建一个迭代器,它从 start
值开始,返回均匀间隔的值。
用法如下:
>>> import itertools
>>> itobj = itertools.count(10)
>>> next(itobj); next(itobj);
>>> next(itobj)
12
itertools.cycle(iterable)
¶
itertools.cycle(iterable)
创建一个迭代器,返回 iterable
中所有元素并保存一个副本。 当取完 iterable
中所有元素,返回副本中的所有元素。无限重复。
>>> it_obj2 = itertools.cycle('ABCD')
>>> next(it_obj2)
'A'
>>> next(it_obj2), next(it_obj2), next(it_obj2), next(it_obj2)
('B', 'C', 'D', 'A')
itertools.repeat(object[, times])
¶
itertools.repeat(object[, times])
创建一个迭代器,不断重复 object
。除非设定参数 times
,否则将无限重复。 这个 object 可以是任意对象。
10 10 10 –>
>>> it_obj3 = itertools.repeat([4,5,6,7],3)
>>> next(it_obj3)
[4, 5, 6, 7]
根据最短输入序列长度停止的迭代器¶
>>> it_obj4 = itertools.accumulate([1,2,3,4,5])
>>> next(it_obj4)
1
>>> next(it_obj4),next(it_obj4),next(it_obj4),next(it_obj4)
(3, 6, 10, 15)
accumulate()
p [,func]
p0, p0+p1, p0+p1+p2, …
accumulate([1,2,3,4,5]) –> 1 3 6 10 15
chain()
p, q, …
p0, p1, … plast, q0, q1, …
chain(‘ABC’, ‘DEF’) –> A B C D E F
chain.from_iterable()
iterable
p0, p1, … plast, q0, q1, …
chain.from_iterable([‘ABC’, ‘DEF’]) –> A B C D E F
compress()
data, selectors
(d[0] if s[0]), (d[1] if s[1]), …
compress(‘ABCDEF’, [1,0,1,0,1,1]) –> A C E F
dropwhile()
pred, seq
seq[n], seq[n+1], … 从pred首次真值测试失败开始
dropwhile(lambda x: x<5, [1,4,6,4,1]) –> 6 4 1
filterfalse()
pred, seq
seq中pred(x)为假值的元素,x是seq中的元素。
filterfalse(lambda x: x%2, range(10)) –> 0 2 4 6 8
groupby()
iterable[, key]
根据key(v)值分组的迭代器
islice()
seq, [start,] stop [, step]
seq[start:stop:step]中的元素
islice(‘ABCDEFG’, 2, None) –> C D E F G
starmap()
func, seq
func(seq[0]), func(seq[1]), …
starmap(pow, [(2,5), (3,2), (10,3)]) –> 32 9 1000
takewhile()
pred, seq
seq[0], seq[1], …, 直到pred真值测试失败
takewhile(lambda x: x<5, [1,4,6,4,1]) –> 1 4
tee()
it, n
it1, it2, … itn 将一个迭代器拆分为n个迭代器
zip_longest()
p, q, …
(p[0], q[0]), (p[1], q[1]), …
zip_longest(‘ABCD’, ‘xy’, fillvalue=‘-’) –> Ax By C- D-
accumulate()
p [,func]
p0, p0+p1, p0+p1+p2, …
accumulate([1,2,3,4,5]) –> 1 3 6 10 15
chain()
p, q, …
p0, p1, … plast, q0, q1, …
chain(‘ABC’, ‘DEF’) –> A B C D E F
chain.from_iterable()
iterable
p0, p1, … plast, q0, q1, …
chain.from_iterable([‘ABC’, ‘DEF’]) –> A B C D E F
compress()
data, selectors
(d[0] if s[0]), (d[1] if s[1]), …
compress(‘ABCDEF’, [1,0,1,0,1,1]) –> A C E F
dropwhile()
pred, seq
seq[n], seq[n+1], … 从pred首次真值测试失败开始
dropwhile(lambda x: x<5, [1,4,6,4,1]) –> 6 4 1
filterfalse()
pred, seq
seq中pred(x)为假值的元素,x是seq中的元素。
filterfalse(lambda x: x%2, range(10)) –> 0 2 4 6 8
groupby()
iterable[, key]
根据key(v)值分组的迭代器
islice()
seq, [start,] stop [, step]
seq[start:stop:step]中的元素
islice(‘ABCDEFG’, 2, None) –> C D E F G
starmap()
func, seq
func(seq[0]), func(seq[1]), …
starmap(pow, [(2,5), (3,2), (10,3)]) –> 32 9 1000
takewhile()
pred, seq
seq[0], seq[1], …, 直到pred真值测试失败
takewhile(lambda x: x<5, [1,4,6,4,1]) –> 1 4
tee()
it, n
it1, it2, … itn 将一个迭代器拆分为n个迭代器
zip_longest()
p, q, …
(p[0], q[0]), (p[1], q[1]), …
zip_longest(‘ABCD’, ‘xy’, fillvalue=‘-’) –> Ax By C- D-
选择元素¶
另外一系列函数根据谓词选取一个迭代器中元素的子集。
itertools.filterfalse(predicate, iter) 和 filter() 相反,返回所有让 predicate 返回 false 的元素:
itertools.filterfalse(is_even, itertools.count())
>>> def is_even(num):
>>> if num %2 == 0:
>>> return True
>>> return False
>>> result = itertools.filterfalse( is_even, the_arr)
>>> list(result)
[1, 3, 5, 7, 9]
组合函数¶
itertools.combinations(iterable, r) 返回一个迭代器,它能给出输入迭代器中所包含的元素的所有可能的 r 元元组的组合。 itertools.permutations(iterable, r=None),取消了保持顺序的限制,返回所有可能的长度为 r 的排列. itertools.combinations_with_replacement(iterable, r) 函数放松了一个不同的限制:元组中的元素可以重复。从概念讲,为每个元组第一个位置选取一个元素,然后在选择第二个元素前替换掉它。
>>> import itertools
>>> x = itertools.combinations([1, 2, 3, 4, 5], 2)
>>> for y in x:
>>> print(y)
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)
>>> z = itertools.permutations([1, 2, 3, 4, 5], 2)
>>> for y in z:
>>> print(y)
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 1)
(2, 3)
(2, 4)
(2, 5)
(3, 1)
(3, 2)
(3, 4)
(3, 5)
(4, 1)
(4, 2)
(4, 3)
(4, 5)
(5, 1)
(5, 2)
(5, 3)
(5, 4)
>>> tt = itertools.combinations_with_replacement([1, 2, 3, 4, 5], 2)
>>> for x in tt:
>>> print(x)
(1, 1)
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 2)
(2, 3)
(2, 4)
(2, 5)
(3, 3)
(3, 4)
(3, 5)
(4, 4)
(4, 5)
(5, 5)
11.4.2. functools 模块¶
functools 模块包含了一些高阶函数。 高阶函数 接受一个或多个函数作为输入,返回新的函数。 这个模块中最有用的工具是 functools.partial() 函数。
对于用函数式风格编写的程序,有时会希望通过给定部分参数,将已有的函数构变形称新的函数。考虑一个 Python 函数 f(a, b, c);你希望创建一个和 f(1, b, c) 等价的新函数 g(b, c);也就是说你给定了 f() 的一个参数的值。这就是所谓的“部分函数应用”。从这一部分感受到更加与数学函数更加相近
partial() 接受参数 (function, arg1, arg2, …, kwarg1=value1, kwarg2=value2)。它会返回一个可调用的对象,所以你能够直接调用这个结果以使用给定参数的 function。
>>> import functools
>>>
>>> def log(message, subsystem):
>>> print('%s: %s' % (subsystem, message))
>>>
>>> server_log = functools.partial(log, subsystem='server')
>>> server_log('start')
server: start
functools.reduce(func, iter, [initial_value])
持续地在可迭代对象的所有元素上执行操作,
因此它不能够用在无限的可迭代对象上。 func
必须是一个接受两个元素并返回一个值的函数。
functools.reduce()
接受迭代器返回的前两个元素 A 和 B 并计算 func(A,
B) 。然后它会请求第三个元素,C,计算 func(func(A, B),
C),然后把这个结果再和第四个元素组合并返回,如此继续下去直到消耗整个可迭代对象。
11.4.3. 对元素使用函数: operator 模块¶
前面已经提到了 operator 模块。它包含一系列对应于 Python 操作符的函数。在函数式风格的代码中,这些函数通常很有用,可以帮你省下不少时间,避免写一些琐碎的仅仅执行一个简单操作的函数。
数学运算: add(),sub(),mul(),floordiv(),abs(), …
逻辑运算: not_(),truth()。
位运算: and_(),or_(),invert()。
比较: eq(),ne(),lt(),le(),gt(),和 ge()。
确认对象: is_(),is_not()。
operator (标准运算符替代函数) 模块包含一组对应于 Python 操作符的函数。比如 operator.add(a, b) (把两个数加起来),operator.ne(a, b) (和 a != b 相同),以及 operator.attrgetter(‘id’) (返回获取 .id 属性的可调用对象)。
>>> the_arr = range(10)
>>> the_arr2 = range(10)
>>> import operator
>>> the_arr3 = operator.add(2,3)
>>> the_arr3
5