Effective Python(一)
第八条: 不要使用含有两个以上(不包含两个)表达式的列表推导
示例一:
把矩阵或二维列表转化为一维列表
>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> flat = [x for row in matrix for x in row]
>>> flat
[1, 2, 3, 4, 5, 6, 7, 8, 9]
示例二:
把矩阵或二维列表的数值平方后构成新的矩阵或二维列表
>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> squared = [[x**2 for x in row] for row in matrix]
>>> squared
[[1, 4, 9], [16, 25, 36], [49, 64, 81]]
以上示例就是在列表中多重循环的合理用法。
问题?
如果表达式里还有一层循环呢?那么列表推导就会变得很长。
>>> my_lists = [[[1, 2, 3], [4, 5, 6]]...]
>>> flat = [x for sublist1 in my_lists
for sublist2 in sublist1
for x in sublist2]
可以看出,这样的代码阅读性非常差,且不简洁。
>>> flat = []
>>> for sublist1 in my_lists:
for sublist2 in sublit1:
flat.append(sublist2)
很明显,这中普通的循环语句带有适当的缩进,看上去比列表推导更加的简洁。
列表推导中也支持if语句
示例三:
从数字列表中选出大于4的偶数,下面两种列表推导方式是等效的。
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> b = [x for x in a if x > 4 if x % 2 == 0]
>>> c = [x for x in a if x > 4 and x % 2 == 0]
>>> b
[6, 8, 10]
>>> c
[6, 8, 10]
示例4:
从原矩阵中把那些本身能为3整除,去其所在行个元素之和有大于等于10的单元格挑出来。
>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> filtered = [[x for x in row if x % 3 == 0] for row in matrix if sum(row) >= 10]
>>> filtered
[[6], [9]]
总结
在实际编程中,有不少缺失适合列表推导的例子。但是,原作者强烈建议大家尽量不要编写这种包含复杂式子的列表推导。这样写会使其他人很难理解这段代码。虽然省下了几行代码,但却会带阅读代码的人带来很大的障碍。