Python标准库中的生成器函数

一、用于过滤的生成器函数

  - 从输入的可迭代对象中产出元素的子集,而不修改元素本身

import itertools

l1 = [1,2,3,4,5]

l2 = [True,False,True,False,True]

def predict(k):

    return l2[k-1]

# compress(it,selector_it)并行处理两个可迭代对象,
# 如果selector_it中的元素是真值,产出it中对应的元素
# 输出: 1,3,5
for i in itertools.compress(l1,l2):
    print(i)

# takewhile(predicate,it)当predicate返回真值时产出对应的元素,然后停止不再继续检查
# 输出:1
for i in itertools.takewhile(predict,l1):
    print(i)

# dropwhile(predicate,it)处理it,跳过predicate计算结果为True的元素后,
# 不再进一步检查,产出剩下的元素
# 输出:2,3,4,5
for i in itertools.dropwhile(predict,l1):
    print(i)

# filter(predicate,it)把it中的各个元素传给predicate,
# 如果predicate(item)返回真,则产出
# 输出:1,3,5
for i in filter(predict,l1):
    print(i)

# filterfalse(predicate,it)与filter类似,逻辑相反
# 输出:2,4
for i in itertools.filterfalse(predict,l1):
    print(i)

# islice(it,stop)作用类似于s[:stop]
# 输出:1,2,3
for i in itertools.islice(l1,3):
    print(i)

# islice(it,start,stop,step=1)作用类似于s[start:stop:step]
# 输出:1,3,5
for i in itertools.islice(l1,0,5,2):
    print(i)

 

二、用于映射的生成器函数

  - 在输入的可迭代对象中的各个元素上做计算,然后返回结果。

import itertools
import operator

l1 = [1,2,3,4,5]

# accumulate(it)产出累计总和
# 输出:1,36,10,15
for i in itertools.accumulate(l1):
    print(i)


def sub(a,b):
    return a-b

# accumulate(it,func)把前两个元素传给func,
# 然后把计算结果和下一个元素传给它,以此类推
# 输出:1,1,1,1,1
for i in itertools.accumulate(l1,min):
    print(i)

# enumerate(it,start=0)产出由两个元素组成的元组,结构是(index,item)
# 其中index从start开始计数,item从it中获取
# 输出:(0,1),(1, 2),(2, 3),(3, 4),(4, 5)
for i in enumerate(l1,0):
    print(i)

def double(k):
    return k*2

# map(func,it)把it中的各个元素传给func,产出结果
# 输出:2,4,6,8,10
for i in map(double,l1):
    print(i)

def join(*a):
    return '_'.join(a)

l1 = ['a','b','c']
l2 = ['a','b','c']
l3 = ['a','b','c']

# map(func,it1,it2,...)如果有多个可迭代对象,
# 那么func必须能接受多个参数,并行处理各个可迭代对象
# 输出:a_a_a,b_b_b,c_c_c
for i in map(join,l1,l2,l3):
    print(i)

# starmap(func,it)把it中各个元素传给func,产出结果
# 这个函数要求it中的元素也是可迭代对象,func的参数类型为*var
# 输出:a,bb,ccc
for i in itertools.starmap(operator.mul,enumerate(l1,1)):
    print(i)

 

三、用于合并的生成器函数

  - 从输入的多个可迭代对象中产出元素

import itertools

l1 = [1,2,3,4]

l2 = [6,7,8,9,10]

# itertools.chain(it1,...,itN) 返回一个生成器
# 先产出it1中所有元素,然后产出it2中所有元素,以此类推
l3 = list(itertools.chain(l1,l2))
# l3: [1, 2, 3, 4, 6, 7, 8, 9, 10]
print('l3:',l3)

# zip(it1,...,itN):返回一个生成器
# 并行从输入的各个可迭代对象中获取元素,产出由N个元素组成的元组
# 只要有一个可迭代对象到头了就停止,不报错
l4 = list(zip(l1,l2))
# l4: [(1, 6), (2, 7), (3, 8), (4, 9)]
print('l4:',l4)


# itertools.chain.from_iterable(it) 返回一个生成器
# 参数it是一个由可迭代对象组成的可迭代对象,函数将这些对象拆分后产出
l5 = list(itertools.chain.from_iterable(l4))
# l5: [1, 6, 2, 7, 3, 8, 4, 9]
print('l5:',l5)

# 但只会拆分一层,不会递归拆分
# l6: [((1, 6), (1, 6)), ((2, 7), (2, 7)), ((3, 8), (3, 8)), ((4, 9), (4, 9))]
l6 = list(zip(l4,l4))
print('l6:',l6)

# l7:[(1, 6), (1, 6), (2, 7), (2, 7), (3, 8), (3, 8), (4, 9), (4, 9)]
l7 = list(itertools.chain.from_iterable(l6))
print('l7:',l7)

l8 = [1,2]
l9 = [3,4]
l10 = [5,6]
# itertools.product(it1,...,itN) 返回一个生成器
# 计算笛卡尔积,从输入的各个可迭代对象中获取元素,合并成由N个元素组成的元组
l11 = list(itertools.product(l8,l9,l10))
# l11:[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]
print('l11:',l11)

# itertools.zip_longest(it1,...,itN,fillvalue=None) 返回一个生成器
# 并行从输入的各个可迭代对象中获取元素,产出由N个元素组成的元组
# 等到最长的可迭代对象到头后才停止,空缺的值用fillvalue填充
l12 = list(itertools.zip_longest(l1,l2,fillvalue='fill'))
# l12: [(1, 6), (2, 7), (3, 8), (4, 9), ('fill', 10)]
print('l12:',l12)

 

四、用于扩展输入的可迭代对象的生成器

import itertools

l1 = [1,2,3,4,5]

# itertools.combinations(it,out_len) 返回一个生成器
# 把it中out_len个元素的组合以元组的形式输出
l2 = list(itertools.combinations(l1,2))
# l2: [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
print('l2:',l2)

# itertools.combinations_with_replacement(it,out_len) 返回一个生成器
# 把it中out_len个元素的组合以元组的形式输出,包括相同元素
l3 = list(itertools.combinations_with_replacement(l1,2))
# l3: [(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)]
print('l3:',l3)

# itertools.count(start=0,step=1) 返回一个生成器
# 从start开始不断产生数字,按step指定的步幅增加
l4 = list(itertools.islice(itertools.count(start=2,step=2),5))
# l4:[2, 4, 6, 8, 10]
print('l4:',l4)

# itertools.cycle(it) 返回一个生成器
# 从it中拿出各个元素的副本,按顺序重复不断地产出各个元素
l5 = list(itertools.islice(itertools.cycle('ABC'),10))
# l5: ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A']
print('l5:',l5)

# itertools.permutations(it,out_len=None) 返回一个生成器
# 生成out_len个it产出的元素的排列
l6 = list(itertools.permutations('ABC'))
# l6: [('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]
print('l6:',l6)

# itertools.repeat(item,[times]) 返回一个生成器
# 重复不断产出指定元素,除非提供times指定次数
l7 = list(itertools.repeat(7,5))
# l7: [7, 7, 7, 7, 7]
print('l7:',l7)

 

五、用于重新排列元素的生成器函数

  - 以某种方式进行重排列

import itertools

# itertools.groupby(it,key=None) 返回一个迭代器
# 产出由两个元素组成的元素,形式为(key,group),其中key是分组标准,
# group是生成器,用于产生分组中的元素
# 使用这个函数之前必须对输入的可迭代对象使用分组标准进行排序,否则输出会混乱

for char, group in itertools.groupby('LLLLAAGGG'):
    # L -> ['L', 'L', 'L', 'L']
    # A -> ['A', 'A']
    # G -> ['G', 'G', 'G']
    print(char,'->',list(group))


animals = ['duck','eagle','rat','giraffe','bear','bat','dolphin','shark','lion']
animals.sort(key=len)


for length,group in itertools.groupby(animals,len):
    # 3 -> ['rat', 'bat']
    # 4 -> ['duck', 'bear', 'lion']
    # 5 -> ['eagle', 'shark']
    # 7 -> ['giraffe', 'dolphin']
    print(length,'->',list(group))

# reversed(seq) 从后向前,倒序产出seq中的元素
# seq必须是序列,或者是实现了__reversed__特殊方法的对象
for length,group in itertools.groupby(reversed(animals),len):
    # 7 -> ['dolphin', 'giraffe']
    # 5 -> ['shark', 'eagle']
    # 4 -> ['lion', 'bear', 'duck']
    # 3 -> ['bat', 'rat']
    print(length,'->',list(group))


# itertools.tee(it,n=2) 返回一个迭代器
# 产生多个迭代器,每个迭代器都和输入的可迭代对象一致
g1,g2,g3 = itertools.tee('ABC',3)
l1 = list(g1)
l2 = list(g2)
l3 = list(g3)
# l1: ['A', 'B', 'C']
print('l1:',l1)
# l2: ['A', 'B', 'C']
print('l2:',l2)
# l3: ['A', 'B', 'C']
print('l3:',l3)

 

posted @ 2019-04-10 21:44  StackNeverOverFlow  阅读(272)  评论(0编辑  收藏  举报