python中列表推导式与生成器表达式对比详解

目录
  • 概述
  • 列表推导式
  • 生成器表达式
  • 使用场景选择
  • 参考
  • 总结

概述

Python中的列表推倒式(List Comprehension) 和 生成器表达式(Generator Expression)是两种很相似的表达式,但含义却不大不同,这里做一个对比。

列表推导式

列表推导式是比较常用的技术,能将本来需要for loop 和 if else 语句的情况简化成一条指令,最终得到一个列表对象:

even = [e for e in range(10) if e % 2 == 0]

具体细节不过多展开,相信很多使用Python的人都已经足够了解这种语法了。

需要注意的一点是,列表推导式不是惰性计算 ( Lazy Loading) 的,因此所有的列表成员都在声明完语句后立即计算 (Eager Loading),因此在数组成员很多的情况下,速度会很慢,例如下面的在IPython环境里面的三个列表推导式的耗时统计:

In [1]: %timeit even = [e for e in range(100000) if e % 2 == 0]
5.5 ms ± 24.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [2]: %timeit even = [e for e in range(1000000) if e % 2 == 0]
58.9 ms ± 440 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [3]: %timeit even = [e for e in range(100000000) if e % 2 == 0]
5.65 s ± 26.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

可以看到随着元素个数的增加,列表推导式执行的时间也相应变长,占用的内存也会变大。

有一种情况是,我们定义了很多很多的数组元素,但是最后并不是所有的元素都能用到,例如经过几条命令,最后可能只有列表里面的前10个元素会用到,或者只有符合某些条件的元素会用到,这样的话,Eager模式就白白花费了时间,白白花费了内存来创建很多用不到的元素,这显然有很大的改进空间。

生成器表达式

生成器能表达式解决上面的问题,它的元素迭代是惰性的,因此只有需要的时候才生产出来,避免了额外的内存开销和时间开销: 生成器表达式不管元素数目多大,创建时都是常数时间,因为它并没有立即创建元素。

那么生成器表达式的语法是怎么样的呢,很简单,只需要把列表推导式中的方括号改为圆括号:

even_gen = (e for e in range(10) if e % 2 == 0)

注意它的类型是生成器类型:

type(even_gen)
# generator

创建生成器表达式的耗时统计:

In [1]: %timeit even_gen = (e for e in range(100000) if e % 2 == 0)
376 ns ± 2.61 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [2]: %timeit even_gen = (e for e in range(10000000) if e % 2 == 0)
382 ns ± 1.63 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [3]: %timeit even_gen = (e for e in range(1000000000) if e % 2 == 0)
384 ns ± 2.85 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

可以看到随着元素的增加,创建时间基本不变,而且比列表推导式的耗时要低不少。

使用场景选择

那么是不是就是说使用中可以用生成器表达式替代列表推导式了呢,也不尽然,因为列表推导式得到的是一个列表,很多便捷操作(如slice等)可以作用到上面,而生成器表达式则不行:

In [17]: even = [e for e in range(10) if e % 2 == 0]

In [18]: even[:3]
Out[18]: [0, 2, 4]

In [19]: even_gen = (e for e in range(10) if e % 2 == 0)

In [20]: even_gen[:3]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [20], in <cell line: 1>()
----> 1 even_gen[:3]

TypeError: 'generator' object is not subscriptable

而且两者有一个致命的区别:生成器表达式只能迭代一次,而列表推导式可以使用很多次,举例如下:

In [22]: even_gen = (e for e in range(10) if e % 2 == 0)

In [23]: for e in even_gen:
    ...:     print(e)
    ...:
0
2
4
6
8

In [24]: for e in even_gen:
    ...:     print(e)
    ...:

可以看到生成器表达式在第二次迭代的时候,里面已经没有元素了!即第一次迭代已经全部生成出来了,而列表推导式是每次迭代都是有相同的内容:

In [25]: even = [e for e in range(10) if e % 2 == 0]

In [26]: for e in even:
    ...:     print(e)
    ...:
0
2
4
6
8

In [27]: for e in even:
    ...:     print(e)
    ...:
0
2
4
6
8

因此总结来说,使用建议如下:

  • 如果要多次迭代时,建议使用列表推导式
  • 如果数组很大或者有无穷个元素,建议使用生成器表达式
  • 其他场景:两者均可,自己看情况使用一个,如果没有速度和方便度的问题即可,如果有问题换另一个再试试

参考

总结

到此这篇关于python中列表推导式与生成器表达式对比的文章就介绍到这了,更多相关python 列表推导式和生成器表达式对比内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python列表推导式,元组推导式,字典推导式,集合推导式

    目录 1 介绍 2 列表推导式 3 元组推导式 4 字典推导式 5 集合推导式 1 介绍 推导式(解析器):是Python独有的一种特性.使用推导式可以快速生成列表.元组.字典以及集合类型的数据,因此推导式又可分为列表推导式. 2 列表推导式 格式: 格式1: [表达式 for 变量 in 列表][out_exp_res for out_exp in input_list] 格式2:[表达式 for 变量 in 列表 if 条件][out_exp_res for out_exp in input

  • python列表推导式的原理及使用方法

    偶尔会在python中看见这样一行代码: data = [x**2 for x in range(0, 5)] # 此时data = [0, 1, 4, 9, 16] 如果不知道背后的语法规则,那么很难理解为什么可以在列表的方括号中写一个“for”循环?实际上,这种语法称为列表推导式,和lambda表达式类似,都是在代码很短的情况下被使用. 本文将从两个方面讲解列表推导式: (1)什么是列表推导式 (2)如何使用列表推导式 1.什么是列表推导式? 列表推导式对应的英文是list comprehe

  • python 列表推导式使用详解

    所谓的列表推导式,就是指的轻量级循环创建列表. 基本使用方式 # 创建一个0-10的列表 a = [x for x in range(11)] print(a) """ 输出结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] """ 上面的列表推导式等价于下面,只是代码非常简化. a = [] for x in range(10): a.append(x) 在循环的过程中使用if # 创建一个1-10之间偶数的列表 a = [x

  • Python 列表推导式需要注意的地方

    原文地址:The Do's and Don'ts of Python List Comprehension 原文作者:Yong Cui, Ph.D. 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:samyu2000 校对者:luochen1992,shixi-li Python 列表推导式并不是给初学者用的,因为它非常反直觉,甚至对于有其他编程语言背景的人也是如此. 我们接触到 List 的使用时,学习的内容都是零散的.所以我们缺少一个关于如何在各种

  • python列表推导式操作解析

    这篇文章主要介绍了python列表推导式操作解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 基本格式 ​[表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件] 例子:将a列表中大于5的数*10储存到b中 一般操作: a = [5,10,15,20] b = [] for n in a: if n > 5: b.append(n*10) print(b) 使用推导式可以令代码简洁 a = [5,10,15

  • python列表推导式实现找出列表中长度大于5的名字

    目录 列表推导式找出列表中长度大于5的名字 任务 我的笨办法 python列表推导式 例如 列表推导式找出列表中长度大于5的名字 任务 给定一个列表,使用列表推导式找出列表中长度大于5的名字,并打印该列表 names = [[‘Tom’, ‘Billy’, ‘Jefferson’, ‘Andrew’, ‘Wesley’, ‘Steven’, ‘Joe’],[‘Alice’, ‘Jill’, ‘Ana’, ‘Wendy’, ‘Jennifer’, ‘Sherry’, ‘Eva’]] 我的笨办法 刚

  • Python之列表推导式最全汇总(中篇)

    目录 前言 列表推导式 语法规范: 初阶实例 1000~2021中包含7的数字有多少 求所有在100到1000之间的水仙花数 通常的解法,条件表达式比较麻,如果是10位数呢 把数字转成字符串,然后遍历计算立方和 一维与二维列表间的互转 实现二维列表的转置 行列互换,首行变首列,尾行变尾列,如下所示: 求列表嵌套的最大深度 求斜边长小于100的勾股数组 实现随机字符串(可作随机密码) 一个四层嵌套的推导式:求k等差数 附录 前言 网传的七天学Python的路线如下,我觉得可以在学过此表中前几天的内

  • Python之列表推导式最全汇总(下篇)

    目录 前言 列表推导式 语法规范: 进阶实例 乘法口诀表 求100以内的质数(或称素数) 求出字符串的所有字串(可推广到所有可切片数据类型) 根据方程式画出字符图 EXCEL表格列号字串转整数 打印Gray格雷码序列 高阶实例 杨辉三角形 斐波那契数列 曼德勃罗集(Mandelbrot Set)分形 附录 前言 网传的七天学Python的路线如下,我觉得可以在学过此表中前几天的内容后,就可以回头来学习一下 列表推导式:它综合了列表.for循环和条件语句. 第一天:基本概念(4小时) : prin

  • python列表推导式 经典代码

    目录 一.什么是推导式 二.条件推导式 1.语法 2.实战练习 三.列表推导式 1.语法 2.实战练习 3.效率对比 四.重点总结 在学习编程过程中,我们不仅要学习python语法,同时也需要学习如何把自己代码写的更美观,效率更高. 一.什么是推导式 推导式是从一个或者多个迭代器快速简洁地创建数据类型的一种方法,它将循环和条件判断结合,从而避免语法冗长的代码,提高代码运行效率.能熟练使用推导式也可以间接说明你已经超越了python初学者的水平. 二.条件推导式 1.语法 ''' value1:如

  • Python之列表推导式最全汇总(上篇)

    目录 前言 列表推导式 语法规范: 入门实例 生成过程 方法一: 方法二: 列表元素间的运算 附录 前言 网传的七天学Python的路线如下,我觉得可以在学过此表中前几天的内容后,就可以回头来学习一下 列表推导式:它综合了列表.for循环和条件语句. 第一天:基本概念(4小时) : print,变量,输入,条件语句. 第二天:基本概念(5小时) :列表,for循环,while循环,函数,导入模块. 第三天:简单编程问题(5小时) :交换两个变量值,将摄氏度转换为华氏温度,求数字中各位数之和, 判

  • Python 列表推导式与字典推导式的实现

    目录 列表推导式 for 循环写法 列表推导式写法 列表推导式还支持嵌套 字典推导式 元组推导式与集合推导式 总结 在 Python 中推导式是一种非常 Pythonic 的知识,本篇博客将为你详细解答列表推导式与字典推导式相关的技术知识. 列表推导式 列表推导式可以利用列表,元组,字典,集合等数据类型,快速的生成一个特定需要的列表. 语法格式如下: [表达式 for 迭代变量 in 可迭代对象 [if 条件表达式]] if 条件表达式 非必选,学完列表推导式之后,你可以发现它就是 for 循环

  • Python列表推导式详情

    目录 1.列表生成式 1.1 案例 2.集合生成式 3.字典生成式 1.列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 语法结构如下: # 普通的生成式 [表达式 for 变量 in 旧列表] # 加条件的生成式 [表达式 for 变量 in 旧列表 if 条件] # if...else条件的生成式 [表达式 if 条件1 else 条件2for 变量 in 旧列表] 1.1 案例 过滤掉名词字母不足4的名字,示

  • python列表推导式入门学习解析

    这篇文章主要介绍了python列表推导式入门学习解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.什么是推导式 推导式是从一个或者多个迭代器快速简洁地创建数据类型的一种方法,它将循环和条件判断结合,从而避免语法冗长的代码,提高代码运行效率.能熟练使用推导式也可以间接说明你已经超越了python初学者的水平. 报错 二.条件推导式 1.语法 ''' value1:如果条件表达式condition成立,返回value1 : 如果条件表达式不成

  • 什么是python的列表推导式

    乍一看到列表推导式你可能会感到疑惑.它们是一种创建和使用列表的简洁方式.理解列表推导式是有用的,因为你可能在其他人的代码里看到列表推导式.下面来了解下列表推导式吧. 数字列表的推导式 回顾之前学过的知识,我们可以创建一个包含前10个数字的列表,如下所示: squares = [] for number in range(1,11): new_square = number**2 squares.append(new_square) for square in squares: print(squ

  • Python列表推导式实现代码实例

    列表推倒式 [结果 for 变量 in 可迭代对象 if 筛选] 字典推倒式 {结果 for 变量 in 可迭代对象 if 筛选} 结果 => key:value 集合推倒式 {结果 for 变量 in 可迭代对象 if 筛选} 结果 => key 自带去重功能 列表推导式的执行顺序:各语句之间是嵌套关系,左边第二个语句是最外层,依次往右进一层,左边第一条语句是最后一层 生成一个存放1-100中个位数为3的数据列表 普通写法 #生成一个存放1-100中个位数为3的数据列表 # 普通写法 lis

  • Python的列表推导式你了解吗

    目录 语法 实例 总结 语法 1.普通 [expression for target in iterable] 2.带条件 [expression for target in iterable if condition] 3.嵌套 [expression for target1 in iterable1 if condition1 for target2 in iterable2 if condition2 ... for targetN in iterableN if conditionN]

  • 简单了解python 生成器 列表推导式 生成器表达式

    生成器就是自己用python代码写的迭代器,生成器的本质就是迭代器. 通过以下两种方式构建一个生成器: 1.通过生成器函数 2.生成器表达式 生成器函数: 函数 def func1(x): x += 1 return x print(func1(5)) 生成器函数 def func1(x): x += 1 yield x g_obj = func1(5) print(g_obj.__next__()) 一个next对应一个yield. yield VS return return 结束函数,给函

  • python之列表推导式的用法

    1. 定义 用一行构建代码 例题 # 构建一个1-100的列表 l1 = [i for i in range(1,101)] print(l1) # 输出结果 [1,2,3,4,5,6,...100] 2. 两种构建方式 2.1 循环模式: [变量(加工后的变量) for 变量 in iterable] 例题 1. 将10以内所有整数写入列表 print([i for i in range(1,11)]) # 输出结果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 2. 将10

随机推荐