itertools想必大家也很困惑yield功用,这次可以阅读内置的itertools库中的函数实现方式,了解yield用法。并且在这过程中熟悉itertools库常用的一些用法。 itertools库可以生产各种迭代器,让迭代更加的高效。 一、 “无限”迭代器无限序列在for迭代时才会无限地迭代下去,如果只是创建了一个迭代对象,它不会事先把无限个元素生成出来。 1.1 count(start,step)生成一个序列,开头start,步长为step的迭代对象。 看源码知道count会无限运行下去。 def count(start=0, step=1):
# count(10) --> 10 11 12 13 14 ...
# count(2.5, 0.5) -> 2.5 3.0 3.5 ...
n = start count()会创建一个无限的迭代器,上述代码会打印出根本停不下来的自然数序列,只能按Ctrl+C退出。 试试这个函数 import itertools ...
1
2
3
4
5
6
... 1.2 cycle()cycle()会把传入的一个序列无限重复下去 def cycle(iterable):
# cycle('ABCD') --> A B C D A B C D A B C D ...
saved = []
#迭代最初的元素
for element in iterable:
yield element
saved.append(element)
#执行完该for循环后,为了继续循环往复下,执行下面的while语句
while saved:
for element in saved:
yield element 试试这个函数 #字符串也是序列的一种abc = itertools.cycle('ABC') ...
'A'
'B'
'C'
'A'
'B'
'C'
... 1.3 repeat()repeat(element,repeat_num) 负责把一个元素element无限重复下去,如果提供第二个参数repeat_num就可以限定重复次数 def repeat(object, times=None):
# repeat(10, 3) --> 10 10 10
if times is None:
while True:
yield object 试试这个函数 #将a重复10次 a
a
a
a
a
a
a
a
a
a 总结:无限序列虽然可以无限迭代下去,但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列
二、操作价值极高的几个函数2.1 chain()chain() 将括号内的所有可迭代对象,共同顺序输出至一个迭代对象。 看英文chain,链条,相当于是把多个可迭代对象拼接起来。 def chain(*iterables):
# chain('ABC', 'DEF') --> A B C D E F
for it in iterables:
for element in it:
yield element 试试这个函数 for x in itertools.chain([['a','b'], ['c','d']], 'DEF'):
print(x) ['a', 'b']
['c', 'd']
D
E
F 2.2groupby()groupby()把迭代器中相邻的重复元素挑出来放在一起,分成不同的部分。 groups = itertools.groupby('AAAABBBCCDAABBB') A ['A', 'A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
D ['D']
A ['A', 'A']
B ['B', 'B', 'B'] groupby的挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。 #看这里,如果groupby()中传入key参数,就可以设置挑选规则。比如大小写都是一样的 如果我们要忽略大小写分组,就可以让元素'A'和'a'都返回相同的key for key, group in itertools.groupby('AaaBBbcCAAa', key=lambda c: c.lower()):
print(key, list(group)) a ['A', 'a', 'a']
b ['B', 'B', 'b']
c ['c', 'C']
a ['A', 'A', 'a'] 2.3 accumulate(iterable, func=operator.add)默认func为累加,具体可看下面运行找规律。 def accumulate(iterable, func=operator.add):
'Return running totals'
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable)
try:
total = next(it)
except StopIteration:
#迭代对象迭代完退出该函数
return
#yield的第一个和
yield total 试试这个函数 for x in itertools.accumulate([1,2,3,4,5]):
print(x) 1
3
6
10
15 2.4 chain.from_iterable()智能传入一个可迭代对象作为参数,并将最多两层嵌套关系摧毁。 def from_iterable(iterables):
#chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
for it in iterables:
for element in it:
yield element 如下,列表嵌套列表 #将[['A','B'],'C']所有元素迭代出来 ['a', 'b']
['c', 'd']
C 2.5 compress(data,selector)data与selector均为可迭代对象,且长度相同。通过selector参数来挑选data中的数据。 selector参数为0或非0。 如果为0,则不返回data中对应的值; 如果为非0,返回data中对应的值。 def compress(data, selectors):
# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
return (d for d, s in zip(data, selectors) if s) 试试这个函数 for x in itertools.compress('ABCDEF',[1,0,1,0,1,1]):
print(x) A
C
E
F for x in itertools.compress('ABCDEF',[-1,0,3,0,1,1]):
print(x) A
C
E
F 2.6 dropwhile(pred, iterable)返回剔除iterable中满足predicate条件的元素后序列。 def dropwhile(predicate, iterable):
# dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x #剔除掉[1,4,6,4,1]中小于5的元素 6
4
1
[6, 4, 1] 2.7 filterfalse()filterfalse(predicate, iterable) 保留iterable中满足predicate条件的元素。 def filterfalse(predicate, iterable):
# filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
if predicate is None:
predicate = bool #保留[0,9)中能被2整除的数 0
2
4
6
8
|
|