许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  Fluent Python读书笔记:第2.2节切片详解

Fluent Python读书笔记:第2.2节切片详解

阅读数 2
点赞 0
article_banner

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

可以写出可读性更好更高效的代码

2.2.1 列表推导和可读性

可读性对比

例1:

>>> symbols = '$¢£¥€¤'

>>> codes = []

>>> for symbol in symbols:

... codes.append(ord(symbol))

...

>>> codes

[36, 162, 163, 165, 8364, 164]

例2:

>>> symbols = '$¢£¥€¤'

>>> codes = [ord(symbol) for symbol in symbols]

>>> codes

[36, 162, 163, 165, 8364, 164]

例2代码的可读性更好。

通常的原则是,只用列表推导来创建新的列表,并且尽量保持简短。如果列表推导的代码超过了两行,你可能就要考虑是不是得用 for 循环重写了。

列表推导不会再有变量泄漏的问题

Python 2.x 中,在列表推导中 for 关键词之后的赋值操作可能会影响列表推导上下文中的同名变量。像下面这个 Python 2.7 控制台对话:

Python 2.7.6 (default, Mar 22 2014, 22:59:38)

[GCC 4.8.2] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> x = 'my precious'

>>> dummy = [x for x in 'ABC']

>>> x

'C'

如你所见,x 原本的值被取代了,但是这种情况在 Python 3 中是不会出现的。

列表推导、生成器表达式,以及同它们很相似的集合(set)推导和字典(dict)推导,在Python 3 中都有了自己的局部作用域,就像函数似的。表达式内部的变量和赋值只在局部起作用,表达式的上下文里的同名变量还可以被正常引用,局部变量并不会影响到它们。

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

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

>>> symbols = '$¢£¥€¤'

>>> beyond_ascii = [ord(s) for s in symbols if ord(s) > 127]

>>> beyond_ascii

[162, 163, 165, 8364, 164]

>>> beyond_ascii = list(filter(lambda c: c > 127, map(ord, symbols)))

>>> beyond_ascii

[162, 163, 165, 8364, 164]

2.2.3 笛卡儿积

笛卡儿积是一个列表,列表里的元素是由输入的可迭代类型的元素对构成的元组,因此笛卡儿积列表的长度等于输入变量的长度的乘积。

>>> 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')]

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

2.2.4 生成器表达式

虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成器表达式是更好的选择。这是因为生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。前面那种方式显然能够节省内存。

用生成器表达式初始化元组和数组

>>> symbols = '$¢£¥€¤'

>>> tuple(ord(symbol) for symbol in symbols)

(36, 162, 163, 165, 8364, 164)

# 如果生成器表达式是一个函数调用过程中的唯一参数,那么不需要额外再用括号把它围起来。

>>> import array

>>> array.array('I', (ord(symbol) for symbol in symbols))

array('I', [36, 162, 163, 165, 8364, 164])

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

使用生成器表达式计算笛卡儿积

>>> colors = ['black', 'white']

>>> sizes = ['S', 'M', 'L']

>>> for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):

... print(tshirt)

...

black S

black M

black L

white S

white M

white L

与前面不同的是,用到生成器表达式之后,内存里不会留下一个有 6 个组合的列表,因为生成器表达式会在每次 for 循环运行时才生成一个组合。


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空