1 概念解释

列表推导是构建列表的快捷方式,生成器表达式可以用来创建其他任何类型的序列。

列表推导:放在方括号里的表达式,使用关键字for与in,通过处理和过滤一个或多个可迭代对象里的元素构建列表。

生成器:使用生成器函数或生成器表达式构建的迭代器,无需迭代集合就可能生成值。生成斐波那契数列的生成器是个典型实例,这个数列是一种无穷序列。

生成器表达式:放在括号里的表达式,句法与列表推导一样,只是返回的是生成器(而不是列表)


2 列表推导

下面的代码有两部分:前一部分使用通常的做法,即使用for循环构造一个新列表;后者使用的是列表推导构建的新列表。

注:ord(‘a’),a为Unicode字符,返回值为字符a对应的Unicode数值;chr(n),n为Unicode数值,返回值为n对应的Unicode字符。

>>> symbols = '*&^%$#!'
>>> codes = []
>>> for symbol in symbols:
...     codes.append(ord(symbol))
...
>>> codes
[42, 38, 94, 37, 36, 35, 33]>>> symbols = '*&^%$#!'
>>> codes = [ord(symbol) for symbol in symbols]
>>> codes
[42, 38, 94, 37, 36, 35, 33]

比较上面的两段代码,可以看出使用列表推导的代码更短,更易于理解。为了防止滥用列表推导,需要注意:只用列表推导来创建新的列表,而且尽量保持简短。若列表推导的代码超过两行,应该考虑使用for循环重写了。总之,这个度得自己把握好。

列表推导可以帮我们把一个序列或其他可迭代类型中的元素过滤或是加工,然后再新建一个列表。

2.1 列表推导同filter和map的比较

filter和map合起来能做的事情,列表推导也可以做,而且还不需要借助难以理解和阅读的lambda表达式。

下面的代码中,分别用列表推导map/filter组合来创建相同的表单:

>>> symbols = '&^%$#@'
>>> beyond_ascii1 = [ord(s) for s in symbols if ord(s) > 38]
>>> beyond_ascii1
[94, 64]>>> beyond_ascii2 = list(filter(lambda c: c > 38, map(ord, symbols)))
>>> beyond_ascii2
[94, 64]

2.2 笛卡尔积

笛卡尔积:两个或两个以上的列表的元素对构成元组,这些元组构成的列表就是笛卡尔积。

用列表推导可以生成两个或以上的可迭代类型的笛卡尔积。笛卡尔积是一个列表,列表里的元素是由输入的可迭代类型的元素对构成的元组。笛卡尔积列表的长度等于输入变量的长度的乘积。


上图是含有4种花色和3种牌面的列表的笛卡尔积,结果是一个包含12个元素的列表。

这是一个例子:现在需要一个列表,列表里是3种不同尺寸的T恤衫,每个尺寸都有2个颜色,下面的代码用列表推导算出了这个列表,共6种组合:

>>> colors = ['black', 'white']
>>> sizes = ['S', 'M', 'L']
>>> tshirts = [(color, size) for color in colors for size in sizes]
>>> tshirts
[('black', 'S'), ('black', 'M'), ('black', 'L'), ('white', 'S'), ('white', 'M'), ('white', 'L')]>>> for color in colors:
...     for size in sizes:
...         print((color, size))
...
('black', 'S')
('black', 'M')
('black', 'L')
('white', 'S')
('white', 'M')
('white', 'L')

上面的代码有两部分,第一部分是使用列表推导,第二部分是使用for循环。这两部分得到的结果都是先以颜色排列,再以尺码排列。而且两个部分的循环嵌套关系先后顺序都一样。

列表推导的作用只有一个——生成列表。 若想生成其他类型的序列,生成器表达式就派上用场了。


3 生成器表达式

虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成器表达式是更好的选择。这是因为生成器表达式背后遵守了迭代器协议,可以逐个地产出元素。生成器表达式的语法跟列表推导差不多,只是把方括号换为圆括号。

下面的代码是一个【用生成器表达式建立元组和数组】的例子:

>>> symbols = '*&^%$'
>>> tuple(ord(symbol) for symbol in symbols) # 1
(42, 38, 94, 37, 36)>>> import array
>>> array.array('I', (ord(symbol) for symbol in symbols)) # 2
array('I', [42, 38, 94, 37, 36])

# 1:若生成器表达式是一个函数调用过程中的唯一参数,则不需要额外再用括号围起来。

# 2:array的构造方法需要两个参数,因此括号是必需的。array构造方法的第一个参数指定了数组中数字的存储方式。

下面的代码利用生成器表达式实现了一个笛卡尔积,用以打印出上文中我们提到过的T恤衫的2种颜色和3种尺码的所有组合。与上文用列表推导的代码相比,用到生成器表达式以后,内存里不会留下一个有6个组合的列表,因为生成器表达式会在每次for循环运行时才生成一个组合。这样的话,可以减少运行开销,如,要计算两个各有1000个元素的列表的笛卡尔积,生成器表达式就可以帮忙省掉运行for循环的可销——即一个含有100万个元素的列表。下面请看代码:

>>> colors = ['black', 'white']
>>> sizes = ['S', 'M', 'L']
>>> for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes): # 1
...     print(tshirt)
...
black S
black M
black L
white S
white M
white L

# 1 生成器表达式逐个产出元素,从来不会一次性产出一个含有6个T恤样式的列表


4 字典推导

字典推导可以从任何以键值对作为元素的可迭代对象中构建出字典。下面的代码是一个例子,展示了利用字典推导可以把一个装满元组的列表编程两个不同的字典:

>>> DIAL_CODES = [(86, 'China'), (91, 'India'), (62, 'Indonesia'), (55, 'Brazil')] # 元组列表
>>> country_code = {country: code for code, country in DIAL_CODES}
>>> country_code
{'China': 86, 'India': 91, 'Indonesia': 62, 'Brazil': 55}
>>> {code: country.upper() for country, code in country_code.items() if code < 66}
{62: 'INDONESIA', 55: 'BRAZIL'}

5 集合推导

集合推导用于构成一个集合。下面的代码是一个例子:新建一个Latin-1字符集合,该集合里的每个字符的Unicode名字里都有’SIGN’这个单词。代码如下:

>>> from unicodedata import name # 1
>>> {chr(i) for i in range(32, 256) if 'SIGN' in name(chr(i), '')} # 2
{'¥', '¬', '©', '+', 'µ', '$', '°', '>', '®', '#', '¤', '§', '%', '=', '÷', '×', '£', '¶', '¢', '<', '±'}

# 1:从unicodedata模块里导入name函数,用于获取字符的名字

# 2:把【编码在32~255之间的字符】的名字里有’SIGN’单词的挑出来,然后放入一个集合里。

列表推导和生成器表达式相关推荐

  1. python关键字列表的表达式,python 列表推导和生成器表达式的使用

    序列 序列是指一组数据,按存放类型分为容器序列与扁平序列,按能否被修改分为不可变序列与可变序列. 容器序列与扁平序列 容器序列存放的是对象的引用,包括list.tuple.collections.de ...

  2. Python 列表推导 、生成器表达式与声明式编程

    1.****列表推导********* 用到函数的一个常见的操作是将其用于列表的所有项,并使用结果创建一个新的列表.例如: # coding=utf-8 ''' ****列表推导********* 用 ...

  3. mysql数据字典生成器_「python技术」列表推导、生成器表达式和字典推导的差异及其示例

    #开往春天新创作大赛# 前言 列表推导式构建列表的快捷方式,而生成器表达式则可以用来创建其他任何类型的序列.自python2.7以后,列表推导和生成器表达式的概念就应用到了字典上,所以就有了字典推导, ...

  4. db2 语句包括不必要的列表_列表推导和生成器表达式的滥用

    列表推导是我在Python中最喜欢的功能之一.所以我写了一篇关于它们的文章进行讨论,并在PyCon 2018上进行了3小时的演讲论述. 虽然我很喜欢列表推导,但我发现一旦新的Pythonistas开始 ...

  5. Python入门之三元表达式\列表推导式\生成器表达式\递归匿名函数\内置函数

    本章目录: 一.三元表达式.列表推导式.生成器表达式 二.递归调用和二分法 三.匿名函数 四.内置函数 ================================================ ...

  6. 列表推导式 生成器表达式

    推导式 comprehensions(又称解析式):是 Python 中很强大的.很受欢迎的特性,具有语言简洁,速度快等优点 列表推导式 就是一个简单的公式,我们用这个列表推导式,把你好几行的for循 ...

  7. format函数python生成列表_python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)...

    一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...

  8. python之生成器(~函数,列表推导式,生成器表达式)

    一.生成器 概念:生成器的是实质就是迭代器 1.生成器的贴点和迭代器一样,取值方式也和迭代器一样. 2.生成器一般由生成器函数或者声称其表达式来创建,生成器其实就是手写的迭代器. 3.在python中 ...

  9. python中创建列表推导身份证号_Python列表推导和生成器表达式

    一.什么是列表推导 # 例1 lst = [] for i in range(1, 11): lst.append(i) print(lst) # 例2 lst = [i for i in range ...

最新文章

  1. Swift -布局框架SnapKit使用
  2. 编程中python怎么读-对Python新手编程过程中如何规避一些常见问题的建议
  3. iOS组件化方案的几种实现
  4. AHPA:开启 Kubernetes 弹性预测之门
  5. Nginx_负载均衡配置讲解
  6. C#的变迁史06 - C# 4.0 之并行处理篇
  7. django 使用requests请求相关接口
  8. 中文翻译The Django Book
  9. matlab 正弦曲线平均值,如何用matlab做正弦曲线拟合
  10. 入侵检测技术期末重点总结
  11. 电偶极子场强分布与电偶极矩的引进_物理量引进_电磁学
  12. 开发对接微信卡包会员卡_微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)...
  13. Matlab | 车辆路径规划应用实例(含源码)
  14. 输入一个四位数字x,分别求出x的个位数字、十位数字、百位数字和千位数字的值 ,并求个位、十位、百位、千位的和 -C语言
  15. VUE踩坑——this.$nextTick、头条小程序组件传值报错问题
  16. 关于魔兽T人和延迟的恶劣挂原理及实现
  17. 仿果壳网手机登陆界面源代码
  18. 开发视频直播APP需要了解的技术原理和技术细节
  19. 扬州大学广陵学院计算机科学与技术女生多吗,超激动!萌新们纷纷晒出与扬大录取通知书合照...
  20. ie8视频播放器兼容

热门文章

  1. Temporal客户端模型
  2. FT2232+OpenOCD为STM32烧录程序步骤
  3. JS(javascript)资
  4. speedoffice(PPT)图片怎么旋转方向
  5. 如何解决Mac电脑在启动时卡在Apple 标志或进度条画面?
  6. 关于trival和non-trivald的理解(人工智能/算法角度)
  7. 申请保密局涉密系统集成资质基本前提和共同性要求
  8. 阿里物联网平台中心网址
  9. 华为路由器DHCP地址池的配置
  10. 智能小车运行及测速原理