Python特性之列表推导式和生成器表达式详解

 更新时间:2023年08月01日 09:23:12   作者:Python数据开发  
这篇文章主要介绍了python语言的两个非常有用的特性:列表推导式和生成器表达式,但是它们之间也有一些重要的区别,我们一起来看看吧

今天我想向你介绍python语言的两个非常有用的特性:列表推导式和生成器表达式。这两个特性都可以让你用一行简洁的代码来创建一个序列,而不需要写循环或者函数。但是它们之间也有一些重要的区别,我们一起来看看吧。

列表推导式

列表推导式是一种用方括号包围的表达式,它可以根据一个或多个迭代器来生成一个列表。例如,如果你想要生成一个包含1到10的平方数的列表,你可以这样写:

squares = [x**2 for x in range(1, 11)]
print(squares)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

你也可以在列表推导式中加入条件判断,来过滤掉一些不想要的元素。例如,如果你只想要生成偶数的平方数,你可以这样写:

even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(even_squares)
# [4, 16, 36, 64, 100]

你还可以在列表推导式中使用多个迭代器,来生成笛卡尔积。例如,如果你想要生成两个列表中所有可能的组合,你可以这样写:

colors = ["red", "green", "blue"]
shapes = ["circle", "square", "triangle"]
combinations = [(c, s) for c in colors for s in shapes]
print(combinations)
# [('red', 'circle'), ('red', 'square'), ('red', 'triangle'), ('green', 'circle'), ('green', 'square'), ('green', 'triangle'), ('blue', 'circle'), ('blue', 'square'), ('blue', 'triangle')]

列表推导式的优点是它可以快速地创建一个列表,并且语法简洁易读。但是它也有一个缺点,就是它会一次性地把所有的元素都存储在内存中,这可能会占用很多空间,尤其是当生成的列表很大或者无限时。这时候,我们就可以使用生成器表达式来解决这个问题。

生成器表达式是一种用圆括号包围的表达式,它和列表推导式非常相似,只是它不会立即生成一个列表,而是返回一个生成器对象。生成器对象是一种特殊的迭代器,它可以按需地产生下一个元素,而不需要提前计算和存储所有的元素。例如,如果你想要生成一个包含1到10的平方数的生成器对象,你可以这样写:

squares_gen = (x**2 for x in range(1, 11))
print(squares_gen)
# <generator object <genexpr> at 0x000001F7E8C6D740>

注意,这里打印出来的不是一个列表,而是一个生成器对象。如果你想要获取生成器对象中的元素,你可以使用next()函数或者for循环来遍历它。例如:

print(next(squares_gen))
# 1
print(next(squares_gen))
# 4
for square in squares_gen:
    print(square)
# 9
# 16
# ...

注意,每次调用next()函数或者遍历生成器对象时,它都会动态地计算下一个元素,并且记住当前的状态。

生成器表达式

生成器表达式的语法和列表推导式基本一致,只是用圆括号代替方括号。你也可以在生成器表达式中加入条件判断和多个迭代器,就像列表推导式一样。例如:

even_squares_gen = (x**2 for x in range(1, 11) if x % 2 == 0)
combinations_gen = ((c, s) for c in colors for s in shapes)

生成器表达式的优点是它可以节省内存空间,因为它不会一次性地创建一个列表,而是按需地产生下一个元素。这样,你就可以处理很大或者无限的序列,而不需要担心内存溢出。例如,如果你想要生成一个无限的斐波那契数列,你可以这样写:

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b
fib_gen = (x for x in fib())

注意,这里我们使用了一个生成器函数来定义斐波那契数列,然后用一个生成器表达式来包装它。生成器函数是一种使用yield语句来返回值的函数,它也会返回一个生成器对象。生成器函数和生成器表达式都是生成器的两种不同的写法,它们都可以用来创建惰性求值的序列。

生成器表达式的另一个优点是它可以提高性能,因为它可以避免不必要的计算和中间变量。例如,如果你想要计算一个序列中所有元素的和,你可以这样写:

total = sum([x**2 for x in range(1, 11)])

但是这样会先创建一个列表,然后再对列表中的元素求和,这样会浪费时间和空间。如果你使用生成器表达式,你可以这样写:

total = sum(x**2 for x in range(1, 11))

这样就不会创建一个列表,而是直接把每个元素的平方数传给sum()函数,这样会更快更省空间。事实上,很多内置的函数都可以接受一个生成器作为参数,例如min(), max(), all(), any()等等。你也可以把一个生成器传给list()函数或者set()函数来转换成一个列表或者集合。

总结

我可以用一个餐厅的例子来比喻列表推导式和生成器表达式。假设你是一个餐厅的老板,你想要给你的客人提供一份菜单,让他们选择自己喜欢的菜品。你有两种方式来制作菜单:

一种是使用列表推导式,也就是提前把所有的菜品都做好,然后放在一个大盘子里,让客人自由挑选。这样的好处是客人可以看到所有的菜品,也可以多次取用,而且速度很快。但是这样的坏处是你需要占用很多的厨房空间和食材,而且有些菜品可能会变凉或者变质,造成浪费。

另一种是使用生成器表达式,也就是根据客人的需求,现场做出一个菜品,然后送到客人的桌子上。这样的好处是你不需要占用很多的厨房空间和食材,而且每个菜品都是新鲜的,不会浪费。但是这样的坏处是客人不能看到所有的菜品,也不能多次取用,而且速度可能会慢一些。

所以,你应该根据不同的情况来选择合适的方式来制作菜单。如果你有很多的客人,而且他们都喜欢吃不同的菜品,那么你可能更适合使用列表推导式。如果你只有少数的客人,而且他们都喜欢吃新鲜的菜品,那么你可能更适合使用生成器表达式。

总之,列表推导式和生成器表达式都是非常有用的特性,它们可以让你用一行简洁的代码来创建一个序列。列表推导式适合于需要多次遍历或者操作的序列,而生成器表达式适合于只需要遍历一次或者处理很大或者无限的序列。你应该根据不同的场景来选择合适的方式来提高你的代码效率和可读性。

到此这篇关于Python特性之列表推导式和生成器表达式详解的文章就介绍到这了,更多相关Python列表推导和生成器表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python time.sleep()是睡眠线程还是进程

    python time.sleep()是睡眠线程还是进程

    这篇文章主要介绍了python time.sleep()是睡眠线程还是进程,通过实例代码给大家介绍了Python Sleep休眠函数 ,需要的朋友可以参考下
    2019-07-07
  • Python 识别录音并转为文字的实现

    Python 识别录音并转为文字的实现

    本文主要介绍了Python 识别录音并转为文字的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • python实现动态规划算法的示例代码

    python实现动态规划算法的示例代码

    本文主要介绍了python实现动态规划算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • python机器学习实现神经网络示例解析

    python机器学习实现神经网络示例解析

    这篇文章主要为大家介绍了python机器学习python实现神经网络的示例解析,在同样在进行python机器学习的同学可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • python面试题小结附答案实例代码

    python面试题小结附答案实例代码

    这篇文章主要介绍了python面试题小结,本文通过实例代码相结合的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • Python处理结构化数据的12个核心模块全解析

    Python处理结构化数据的12个核心模块全解析

    ​在Python数据生态中,JSON模块因其轻量级和跨语言特性成为最常用的结构化数据处理工具,本文将深入探讨12个核心模块,覆盖表格数据、二进制序列化、配置管理、科学计算等六大场景,结合真实案例解析其技术特性,快跟随小编一起了解下吧
    2025-10-10
  • Tensorflow2.1 MNIST图像分类实现思路分析

    Tensorflow2.1 MNIST图像分类实现思路分析

    这篇文章主要为大家介绍了Tensorflow2.1 MNIST图像分类实现思路分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 使用豆瓣提供的国内pypi源

    使用豆瓣提供的国内pypi源

    PyPI(Python Package Index)是python官方的第三方库的仓库,所有人都可以下载第三方库或上传自己开发的库到PyPI。PyPI推荐使用pip包管理器来下载第三方库。
    2017-07-07
  • Python将DataFrame的某一列作为index的方法

    Python将DataFrame的某一列作为index的方法

    下面小编就为大家分享一篇Python将DataFrame的某一列作为index的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04
  • pytorch自定义loss损失函数

    pytorch自定义loss损失函数

    这篇文章主要介绍了pytorch自定义loss损失函数,自定义loss的方法有很多,本文要介绍的是把loss作为一个pytorch的模块,下面详细资料需要的小伙伴可以参考一下
    2022-02-02

最新评论