文章目录
- 一、推导式
- 1.列表推导式
- 2.字典推导式
- 3.集合推导式
- 4.元组推导式(生成器推导式)
- 二、生成器
- 1.生成器表达式
- 2.生成器函数
- 3.send函数
- 结束语
- 💂 个人主页:风间琉璃
- 🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主
- 💬 如果文章对你有
帮助
、欢迎关注
、点赞
、收藏(一键三连)
和订阅专栏
哦
一、推导式
Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。
Python 支持各种数据结构的推导式:
列表(list)推导式
字典(dict)推导式
集合(set)推导式
元组(tuple)推导式
1.列表推导式
列表推导式(根据for循环化简而来),其功能:利用表达式生成一个有规律的列表,列表推导式又叫列表生成式,简化代码量。语法如下:
[表达式 for 变量 in 列表]
[out_exp_res for out_exp in input_list]
或者
[表达式 for 变量 in 列表 if 条件]
[out_exp_res for out_exp in input_list if condition]
其中 for 前面的表达式
为返回值
。
⋆
\star
⋆ out_exp_res:列表生成元素表达式
,可以是有返回值的函数
。
⋆
\star
⋆ for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中。
⋆
\star
⋆if condition:条件语句
,可以过滤列表中不符合条件的值。
利用列表生成式生成偶数:
计算 30 以内可以被 3 整除的整数:
多个for实现列表推导式:多个for循环的列表推导式等同于for循环的嵌套,其可以打印多个数据组成的数据序列中(可以是列表、元组、集合)。
列表名 = [ (表达式1, 表达式2) for 变量 in 列表 for 变量 in 列表]
列表名 = [ (i的返回值,j的返回值) for i in range() for j in range()]
举例:
2.字典推导式
字典推导基本格式:
{ key_expr: value_expr for value in collection }
或
{ key_expr: value_expr for value in collection if condition }
作用1:其可以快速将两个列表进行合并为字典或者提取字典中的目标数据。
字典名 = { i 的返回值:value值 for i in range(start,end,step)}
利用字典推导式完成需求,字典的key为1—5的数字,字典的value为key的2次方
作用2:将两个列表合并,注意:两个列表长度一致,len()取哪个长度都可以,长度不一致,要用len()取长度小的,否则会报错。
字典名 = { 列表1[ i ] :列表2[ i ] for i in range(len(列表名))}
作用3:提取字典中的目标数据
字典名 = {key:value for key,value in 字典序列 . items() if 判断条件}
有一个字典 dict1= {“C语言”:18,“数据结构”:“16”,“计网”:8},提取这个字典中兴趣爱好人数大于10的键值对并保存到另外一个字典中。
3.集合推导式
集合推导式基本格式:
{ expression for item in Sequence }
或
{ expression for item in Sequence if conditional }
集合名 = {i处理后的返回值 for i in 列表序列}
可以通过列表生成具有一定规则的集合。
计算数字 1,2,3 的平方数:
判断不是 abc 的字母并输出:
4.元组推导式(生成器推导式)
元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。
元组推导式基本格式:
(expression for item in Sequence )
或
(expression for item in Sequence if conditional )
生成一个包含数字 1~9 的元组:
二、生成器
通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量是有限的。而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。
在Python中,这种一边循环一边计算的机制,称为生成器:generator。生成器(generator)
也是一种迭代器
,在每次迭代时返回一个值,直到抛出 StopIteration 异常。它有两种构造方式:
1.生成器表达式
生成器表达式其实就是元组推导式,和列表推导式的定义类似,生成器表达式使用 () 而不是 [] 。
生成器表达式无法像列表推导式那样直接输出,它和可迭代对象一样只能采用for循环调用next()函数,原因在于range返回的是一个可迭代对象,列表推导式之所以能直接print就是因为[]将可迭代对象转为列表。
2.生成器函数
在 Python 中,使用了yield
的函数被称为生成器(generator)
。
yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数
,可以在迭代过程中逐步产生值,而不是一次性返回所有结果
。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
当在生成器函数中使用yield
语句时,函数的执行将会暂停
,并将 yield 后面的表达式作为当前迭代的值返回。然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。
从上面可以知道,调用一个生成器函数
,返回的是一个迭代器对象
。其执行过程如下:
(1)调用该函数的时不会立即执行代码,而是返回了一个生成器对象。
(2)当使用 next() (在 for 循环中会自动调用 next() ) 作用于返回的生成器对象时,函数开始执行,在遇到 yield 的时会
暂停
,并返回当前的迭代值
。(3)当再次使用 next() 时,函数会从原来暂停的地方继续执行,直到遇到 yield语 句,如果没有 yield 语句,则抛出异常。
整个过程看起来就是不断地执行->中断->执行->中断的过程。一开始,调用生成器函数的时候,函数不会立即执行,而是返回一个生成器对象;然后,当我们使用 next() 作用于它的时候,它开始执行,遇到 yield 语句的时候,执行被中断,并返回当前的迭代值,要注意的是,此刻会记住中断的位置和所有的变量值,即执行时的上下文环境被保留起来;当再次使用 next() 的时候,从原来中断的地方继续执行,直至遇到 yield ,如果没有 yield ,则抛出异常。简而言之,next 使函数执行, yield 使函数暂停
。
使用示例:
def countdown(n):
while n > 0:
yield n
n -= 1
# 创建生成器对象
generator = countdown(5)
# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3
# 使用 for 循环迭代生成器
for value in generator:
print(value) # 输出: 2 1
countdown 函数是一个生成器函数。它使用 yield 语句逐步产生从 n 到 1 的倒数数字。在每次调用 yield 语句时,函数会返回当前的倒数值,并在下一次调用时从上次暂停的地方继续执行。
通过创建生成器对象并使用 next() 函数或 for 循环迭代生成器,可以逐步获取生成器函数产生的值。在这个例子中,首先使用 next() 函数获取前三个倒数值,然后通过 for 循环获取剩下的两个倒数值。
生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。
注意:调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误
,返回值包含在StopIteration
的value
中。
3.send函数
除了可以使用next()函数来唤醒,让生成器继续执行外,还可以使用send()函数来唤醒执行
。使用send()函数的一个好处是:可以在唤醒的同时向断点处传入一个附加数据。
使用send修改上面的代码,示例如下:
send会让生成器从上次停止的位置继续开始执行,并且会将11传递到生成器中,当做上一次执行yield 100 这个表达式的结果,即num = 11。
小结:
1.使用了yield关键字
的函数不再是函数,而是生成器
。
2.yield关键字有两点作用:
①保存当前运行状态(断点
),然后暂停执行,即将生成器(函数)挂起
②将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
3.可以使用next()函数
让生成器从断点处继续执行
,即唤醒生成器(函数)
4.Python3中的生成器可以使用return返回最终运行的返回值
5.生成器,它可以记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
6.生成器的特点:存储的是生成数据的方式(即算法),而不是存储生成的数据,因此节约内存
。
结束语
感谢阅读吾之文章,今已至此次旅程之终站 🛬。
吾望斯文献能供尔以宝贵之信息与知识也 🎉。
学习者之途,若藏于天际之星辰🍥,吾等皆当努力熠熠生辉,持续前行。
然而,如若斯文献有益于尔,何不以三连为礼?点赞、留言、收藏 - 此等皆以证尔对作者之支持与鼓励也 💞。