流畅的 Python(16):序列构成的数组 2.2.4

阅读数:7 2019 年 11 月 20 日 16:56

流畅的Python(16):序列构成的数组 2.2.4

内容简介
本书致力于帮助 Python 开发人员挖掘这门语言及相关程序库的优秀特性,避免重复劳动,同时写出简洁、流畅、易读、易维护,并且具有地道 Python 风格的代码。本书尤其深入探讨了 Python 语言的高级用法,涵盖数据结构、Python 风格的对象、并行与并发,以及元编程等不同的方面。

(生成器表达式)

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

生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已。

示例 2-5 展示了如何用生成器表达式建立元组和数组。

示例 2-5 用生成器表达式初始化元组和数组

>>> 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 构造方法的第一个参数指定了数组中数字的存储方式。2.9.1 节中有更多关于数组的详细讨论。

示例 2-6 则是利用生成器表达式实现了一个笛卡儿积,用以打印出上文中我们提到过的 T 恤衫的 2 种颜色和 3 种尺码的所有组合。与示例 2-4 不同的是,用到生成器表达式之后,内存里不会留下一个有 6 个组合的列表,因为生成器表达式会在每次 for 循环运行时才生成一个组合。如果要计算两个各有 1000 个元素的列表的笛卡儿积,生成器表达式就可以帮忙省掉运行 for 循环的开销,即一个含有 100 万个元素的列表。

示例 2-6 使用生成器表达式计算笛卡儿积

>>> 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 个 T 恤样式的列表。

第 14 章会专门讲到生成器的工作原理。这里只是简单看看如何用生成器来初始化除列表之外的序列,以及如何用它来避免额外的内存占用。

接下来看看 Python 中的另外一个很重要的序列类型:元组(tuple)。

图灵地址 https://www.ituring.com.cn/book/1564

评论

发布