迭代器在Python中是一种特殊的对象,它允许按顺序访问容器中的元素, 而不需要一次性将所有元素加载到内存中。这使得迭代器在处理大型数据集或无限序列时特别有用, 因为它可以帮助节省内存并提高性能。
itertools
模块包含很多常用的迭代器以及用来组合迭代器的函数。
这个模块实现一系列 iterator
,这些迭代器受到APL,Haskell
和 SML
的启发里的函数大致可以分为几类:
已有的迭代器创建新的迭代器的函数。
接受迭代器元素作为参数的函数。
选取部分迭代器输出的函数。
给迭代器输出分组的函数。
import itertools
itobj = itertools.count(10)
next(itobj); next(itobj);
next(itobj)
12
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')
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])
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-
def is_even(num):
if num %2 == 0:
return True
return False
result = itertools.filterfalse( is_even, the_arr)
list(result)
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)
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)
,
然后把这个结果再和第四个元素组合并返回,如此继续下去直到消耗整个可迭代对象。
前面已经提到了 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