Python进阶之推导式与生成器

编程入门 行业动态 更新时间:2024-10-14 02:25:46

Python<a href=https://www.elefans.com/category/jswz/34/1769503.html style=进阶之推导式与生成器"/>

Python进阶之推导式与生成器

文章目录

  • 一、推导式
    • 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 nn -= 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错误,返回值包含在StopIterationvalue中。

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.生成器的特点:存储的是生成数据的方式(即算法),而不是存储生成的数据,因此节约内存

结束语

感谢阅读吾之文章,今已至此次旅程之终站 🛬。

吾望斯文献能供尔以宝贵之信息与知识也 🎉。

学习者之途,若藏于天际之星辰🍥,吾等皆当努力熠熠生辉,持续前行。

然而,如若斯文献有益于尔,何不以三连为礼?点赞、留言、收藏 - 此等皆以证尔对作者之支持与鼓励也 💞。

更多推荐

Python进阶之推导式与生成器

本文发布于:2023-11-16 19:01:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1632298.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:进阶   生成器   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!