python标准库中的24个生成器函数,个个都超级厉害,你用过几个?

前言

标准库提供了很多生成器,有些是内置的,有些在itertools和functools模块中,下面我们就按照它们的功能进行分组来看看它们吧!

用于过滤的生成器函数

import itertools

# itertools.compress(it,selector_it)
# 并行处理两个可迭代对象,如果selector_it中的元素是真值,产出it中对应的元素
print([i for i in itertools.compress(range(10), [0, 0, 1, 1])])

# itertools.takewhile(predicate,it)
# 使用传入的生成器生成另一个生成器,predicate指定终止条件
print([i for i in itertools.takewhile(lambda n: n < 5, range(10))])

# itertools.dropwhile(prdicate,it)
# 与itertools.takewhile的作用相反
print([i for i in itertools.dropwhile(lambda n: n < 5, range(10))])

# filter(predicate,it)
# 将it中的各个元素传给predicate,如果为真,则产出it中对应的元素
print([i for i in filter(lambda a: a % 2, range(10))])  # 保留奇数

# itertools.filterfalse(predicate,it)
# 与filter的作用相反
print([i for i in itertools.filterfalse(lambda a: a % 2, range(10))])  # 保留偶数

# itertools.islice(it,stop)或者itertools.islice(it,start,stop,step=1)
# 产出it的切片 实现的是惰性操作
print([i for i in itertools.islice(range(10), 2)])
print([i for i in itertools.islice(range(10), 2, 9, 3)])

#end

用于映射的生成器函数

 

import itertools
import fractions
import operator

# itertools.accumulate(it,func)
# 产出累积的总和,如果提供了func,那么把前两个元素传给它,然后把计算的结果和下一个元素传给它,以此类推
print([i for i in itertools.accumulate(range(10), lambda a, b: a + b)])  # 计算前n项的和

# enunerate(it,start=0)
# 产出由两个元素构成的元组 结构是(index,item) index从start开始,每次加一 item的值中it中取
print([i for i in enumerate(range(10), start=10)])

# map(func,iter,[it2,...itn])
# 把it中的各个元素传给func,产出结果,如果传入n个it,func的参数必须有n个
print([i for i in map(lambda a, b, c: a + b + c, range(-10, 0, 1), range(10), range(10, 20))])  # 对it1,it2,it3对应位置的元素进行求和
# itertools.startmap(func,it)
# 把it中的各个元素传给func,产出结果
print([i for i in itertools.starmap(operator.mul, enumerate('hello world', 1))])  # 从1开始,根据字母所在位置,把字母重复相应的次数

 合并多个可迭代对象的生成器函数

import itertools

# itertools.chain(it1,[it2...it2])
# 先产出it1中的元素,然后产出it2中的元素,以此类推,无缝连接在一起
print([i for i in itertools.chain(range(10), range(11, 20), 'hello world')])

# itertools.chain.from_iterable(it)
# 功能同itertools.chain 不过传入的参数的结构有所变化   it的结构:it=[iter1,[iter2...itern]]
print([i for i in itertools.chain.from_iterable([range(10), 'hello'])])

# itertools.product(it1,...itn,repeat=1)
# 计算笛卡尔积,从输入的各个可迭代对象中获取元素,合并成由N个元素组成的元组,与嵌套的for循环效果一样,repeat指明重复处理多少次输入的可迭代对象
print([i for i in itertools.product(range(3), 'hello', 'world', repeat=1)])

# zip(it1,...itn)
# 并行从输入的各个可迭代对象中获取元素,产出由N个元素组成的元组,只要有一个可迭代对象到了头,迭代就终止
print([i for i in zip(range(5), 'hello')])

# zip_longest(it1,..itn,fillvalue=None)
# 与zip作用一样,但是终止条件是最长的可迭代对象到头了才终止,其他可迭代对象空缺的值用fillvalue进行补充
print([i for i in itertools.zip_longest(range(10), 'hello', fillvalue='world')])

 把输入的各个元素扩展成多个输出元素的生成器函数

import itertools

# itertools.combinations(it,out_len)  组合 和顺序无关
# 把it产出的out_len个元素组合在一起,然后产出
print([i for i in itertools.combinations('ABC', 2)])  # 产出两两组合的元素

# itertools.combinations_with_replacement 组合
# 功能同itertools.combinations,但是也包含自己和自己的组合
print([i for i in itertools.combinations_with_replacement('ABC', 2)])

# itertools.count(start=0,step=1)
# 从start开始,以step为步长,不断产出数字
for i in itertools.count(1, 2):
    print(i, end=' ')
    if i > 10: break
print()

# itertools.permutations(it,out_len=len(list(it)))
# 把it产出的out_len个元素排列在一起  排列  和顺序有关
print([i for i in itertools.permutations('ABC', 2)])

# repeat(item,[times])
# 重复不断的产出指定的元素,除非提供times指定次数
print([i for i in itertools.repeat('hello', 10)])

# itertools.cycle(it)
# 从it中产出各个元素,存储各个元素的副本,然后按顺序重复不断地产出各个元素
cy = itertools.cycle('ABC')  # 将it首位相连
while True:
    print(next(cy))
    break

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

import itertools

# itertools.groupby(it,key=None)
# 产出由练个元素组成的元素,形式为(key,group),其中key是分组标准,group是生成器,用于产出分组里的元素
strs_list = ['hello', 'world', 'we', 'price', 'the', 'things', 'when', 'we', 'have', 'lost', 'them', '.']
strs_list.sort(key=len)  # 先排序
for key, group in itertools.groupby(strs_list, key=len):  # 根据元素的长度进行分组
    print(key, list(group))

# reversed(seq)
# 从后向前,倒序产出seq seq必须是序列,或者是实现了__reversed__的对象
print(list(reversed(strs_list)))

# itertools.tee(it,n=2)
# 产出一个由n个生成器组成的元组,每个生成器用于单独产出输入的可迭代对象中的元素
g1, g2 = itertools.tee('ABC')
print(list(g1))
print(list(g2))

 

总结

python的大部分的内置功能都是用c实现的,这些生成器函数也不例外,它们不仅功能强大,性能也是相当不错的,因此,掌握它们对你的代码优化上会有不小的帮助哦!

同步更新于个人博客系统:python标准库中的24个生成器函数,个个都超级厉害,你用过几个?

参考资源链接:[使用 Python 生成爱心函数和动画效果](https://wenku.youkuaiyun.com/doc/1k93ywbis6?utm_source=wenku_answer2doc_content) 要创建一个动态变化的爱心动画效果,你可以使用tkinter库来实现GUI,并结合数学函数和随机数生成器来定义爱心的形状和动态变化效果。在你开始之前,先来了解一下《使用 Python 生成爱心函数和动画效果》这份高级炫酷爱心代码的资源,它将为你提供一个基础框架和深入理解如何在Python中运用数学知识来绘制图形。 首先,你需要定义一个爱心函数,通常这个函数会基于参数方程来描述爱心的轮廓。例如,一个常见的爱心函数可以表示为: ```python def heart_function(t, shrink_ratio): x = 16 * shrink_ratio * np.sin(t)**3 y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t) return (x, y) ``` 其中,参数`shrink_ratio`用于控制爱心的大小。使用`numpy`库可以方便地进行数学运算。 接下来,使用tkinter库创建一个窗口,并在窗口中绘制爱心图形。你可以使用`Canvas`组件来绘制图形,并且定时更新图形的位置或者大小来创建动画效果。例如: ```python import tkinter as tk import numpy as np root = tk.Tk() canvas = tk.Canvas(root, width=400, height=400) canvas.pack() # 初始化参数 shrink_ratio = 1 last_time = None def update_heart(): global shrink_ratio, last_time if last_time is not None: elapsed = time.time() - last_time shrink_ratio = max(0.1, shrink_ratio - elapsed / 10) else: last_time = time.time() draw_heart(shrink_ratio) root.after(10, update_heart) def draw_heart(shrink_ratio): canvas.delete('heart') for t in np.linspace(0, 2*np.pi, 200): x, y = heart_function(t, shrink_ratio) canvas.create_oval(x-2, y-2, x+2, y+2, fill='red', tags='heart') last_time = time.time() update_heart() root.mainloop() ``` 在这个例子中,`update_heart`函数会在一定时间间隔内调用`draw_heart`函数来绘制爱心,并且通过改变`shrink_ratio`来实现大小变化的效果。使用`root.after`方法可以设置定时器,以固定的时间间隔更新爱心动画。 此外,你还可以通过添加更多的数学函数来生成不同的动态效果,比如使用随机数生成器来改变爱心颜色,或者在爱心周围生成随机点阵,增加动画的多样性。 最后,为了更全面地掌握tkinter和Python编程中的动画效果,建议在学习了基础的动画实现后,继续深入探索《使用 Python 生成爱心函数和动画效果》中的高级技巧,这份资料不仅涵盖了爱心动画的生成,还提供了许多实用的示例和深入的解释,帮助你提升编程能力,实现更加炫酷的图形界面设计。 参考资源链接:[使用 Python 生成爱心函数和动画效果](https://wenku.youkuaiyun.com/doc/1k93ywbis6?utm_source=wenku_answer2doc_content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值