本文最后更新于:2022年8月5日 晚上
列表推导是构建列表(list)的快捷方式,可以使得代码可读性更好、效率更高。
列表推导
语法示例
1 2 3 4 5 6 7 symbols = '$¢£¥€¤' codes = [ord (symbol) for symbol in symbols] --> codes [36 , 162 , 163 , 165 , 8364 , 164 ]
可以代替 for 循环创建列表
通常使用列表推导的原则是:只用列表推导来创 建新的列表,并且尽量保持简短。
Python 会忽略代码里 []、{}
和 ()
中的换行,因此如果你的代码里 有多行的列表、列表推导、生成器表达式、字典这一类的,可以省 略不太好看的续行符 \
。
列表推导不会再有变量泄漏的问题,列表推导、生成器表达式,以及同它们很相似的集合(set)推导 和字典(dict)推导,在Python3 中都有了自己的局部作用域,就像函数似的。表达式内部的变量和赋值只在局部起作用,表达式的上下文里的同名变量还可以被正常引用,局部变量并不会影响到它们。
列表推导同filter 和map 的比较
filter 和 map 合起来能做的事情,列表推导也可以做,而且还不需要 借助难以理解和阅读的 lambda 表达式。
1 2 3 symbols = '$¢£¥€¤' beyond_ascii = [ord(s) for s in symbols if ord(s) > 127 ]beyond_ascii = list(filter(lambda c: c > 127 , map(ord, symbols)))
笛卡儿积
用列表推导可以生成两个或以上的可迭代类型的笛卡儿积。 笛卡儿积是一个列表,列表里的元素是由输入的可迭代类型的元素对构 成的元组,因此笛卡儿积列表的长度等于输入变量的长度的乘积。
含有 4 种花色和 3 种牌面的列表的笛卡儿积,结果是一个包 含 12 个元素的列表
1 2 3 4 5 6 7 8 9 10 suit = ['Diamonds_' , 'Spades_' , 'Clubs_' , 'Hearts_' ] ranks = [str(index) for index in range(1,11)] + ['J' , 'Q' , 'K' , 'A' ] cards = [suit+rank for suit in suits for rank in ranks] --> cards['Diamonds_1' , 'Diamonds_2' , 'Diamonds_3' , 'Diamonds_4' , 'Diamonds_5' , 'Diamonds_6' , 'Diamonds_7' , 'Diamonds_8' , 'Diamonds_9' , 'Diamonds_10' , 'Diamonds_J' , 'Diamonds_Q' , 'Diamonds_K' , 'Diamonds_A' , ...] len (cards) 56
生成器表达式
虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成 器表达式是更好的选择。这是因为生成器表达式背后遵守了迭代器协 议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这 个列表传递到某个构造函数里。前面那种方式显然能够节省内存。
生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已。
1 2 3 4 5 6 7 8 9 10 11 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 构造 方法的第一个参数指定了数组中数字的存储方式。
使用生成器生成扑克牌:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 suit = ['Diamonds_' , 'Spades_' , 'Clubs_' , 'Hearts_' ] ranks = [str(index) for index in range(1 ,11 )] + ['J' , 'Q' , 'K' , 'A' ] for card in (suit+rank for suit in suits for rank in ranks): print(card) -->Diamonds_1 Diamonds_2 Diamonds_3 Diamonds_4 Diamonds_5 Diamonds_6 Diamonds_7 Diamonds_8 Diamonds_9 Diamonds_10 Diamonds_J Diamonds_Q Diamonds_K Diamonds_A Spades_1 Spades_2 Spades_3 ...
参考资料
文章链接:
https://www.zywvvd.com/notes/coding/python/fluent-python/chapter-2/list-generator/list-generator/