我认为表达式[(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]中唯一令人困惑的部分是隐藏了一个隐式flatten操作。在
让我们先考虑一下表达式的简化版本:
def even(x):
return x % 2 == 0
def odd(x):
return not even(x)
c = map(lambda x: map(lambda y: [x, y],
filter(odd, range(5))),
filter(even, range(5)))
print(c)
# i.e. for each even X we have a list of odd Ys:
# [
# [[0, 1], [0, 3]],
# [[2, 1], [2, 3]],
# [[4, 1], [4, 3]]
# ]
flattened = [x for sublist in c for x in sublist]
print(flattened)
# ... which is basically an equivalent to:
# result = []
# for sublist in c:
# for x in sublist:
# result.append(x)
要附加到@Kasramvd's explanation的注释。在
可读性在Python中很重要。这是语言的特点之一。许多人会认为列表理解是唯一可读的方式。在
然而,有时,尤其是当你在处理多个条件迭代时,将你的标准与逻辑分开会更清楚。在这种情况下,可以优选使用函数方法。在
需要注意的一点是,嵌套列表的理解是O(n2)顺序。意思是它在两个范围的乘积上循环。如果要使用
map
和filter
,则必须创建所有组合。你可以在过滤之后或之前做这些,但是不管你做什么,你都不可能拥有这两个函数的所有这些组合,除非你改变范围和/或修改其他东西。在一种完全实用的方法是使用},如下所示:
itertools.product()
和{还请注意,使用两次迭代的嵌套列表理解基本上比多个
map
/filter
函数更具可读性。当你的函数仅仅是内置函数时,使用内置函数的性能要比列表理解快得多,这样你就可以确保它们都是在C级别上执行的。当你用一个lambda
函数这样的Python/higher lever操作来打破这个链,你的代码不会比列表理解快。在我认为表达式
[(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]
中唯一令人困惑的部分是隐藏了一个隐式flatten
操作。在让我们先考虑一下表达式的简化版本:
然而,我们需要的是完全相同但扁平化的列表
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
。在从official python docs我们可以得到
^{pr2}$flatten
函数的示例:它基本上相当于以下列表理解表达式:
相关问题 更多 >
编程相关推荐