我有以下代码:
[e for e in [sl] for sl in [1,[2,3],4,5]]
我认为(在输出方面)相当于:
[sl for sl in [1,[2,3],4,5]]
然而,后者产生:[1,[2,3],4,5]
前者返回:[5, 5, 5, 5]
我认为它必须与嵌套for-statements
的评估方式有关。
我在Weird behavior: Lambda inside list comprehension发现了一个类似的案例,但由于它使用了匿名函数,因此这种行为背后的原因应该是不同的。
显然,我有一些遗失的东西,我不知道。
感谢您的任何澄清
更新
帕特里克指出,两个for
的顺序是错误的,除非之前定义sl
,否则不应该运行。我在这里骗了自己,因为我在解释器中运行了示例,[sl for sl in [1,[2,3],4,5]]
首先执行,sl
设置为globals()
现在了解如何评估
会很棒[e for e in [sl] for sl in [1,[2,3],4,5]]
以便在输出中生成[5, 5, 5, 5]
。
答案 0 :(得分:2)
代码中的其他地方是否定义了sl
?也许是5
?如上所述,您的第一个示例不应该运行,并且不会在Python 3.6中运行。写它的正确方法是
[e for sl in [1,[2,3],4,5] for e in [sl]]
请注意,此处sl
在使用之前已定义。
编辑:
Python从左到右读取列表推导。当它到达for e in [sl]
时,它会根据已知的内容评估表达式[sl]
,而不会读取该行的其余部分。列表理解就像是
[e for e in [5] for sl in [1,[2,3],4,5]]
由于sl
中有四个[[1,[2,3],4,5]]
,因此您会在结果列表中获得5
四次。
在编写列表推导时,将它们从最小到最大编写
是很自然的e for e in x for x in y for y in z #wrong
但实际上你应该从右到左编写它们,以便解释器识别你在嵌套理解中使用的标识符
e for y in z for x in y for e in x
这与常规for
循环没有区别:
for e in x:
for x in y:
for y in z:
print(e)
显然是错误的,列表推导也没有什么不同。
答案 1 :(得分:0)
代码可以运行的唯一方法是在其他位置定义sl
。如果是(如5
),那么代码:
sl = 5
[e for e in [sl] for sl in [1,[2,3],4,5]]
产生输出:
[5,5,5,5]
<强>为什么吗
发生这种情况的原因是从for-loops
到evaluate
的{{1}} left
。所以第一件事就是将right
分配给e
- 正如您可能的那样:
5
会给[i for i in [9]]
。
现在我们知道,无论最右边的9
如何,for-loop
的值始终都是e
的值,所以在我们的案例中sl
。现在,为什么输出5
?好吧它令人困惑,因为变量[5,5,5,5]
正在重复使用。但是,这不会影响sl
的{{1}},因为它会将left
评估为list-comprehension
。因此left
始终具有right
(e
)的值,无论右侧是[sl]
。右手5
只是作为一个反击。由于其中包含sl
个元素(loop
,4
,1
,[2,3]
),因此左侧部分运行4
次。但5
始终为4
,因此每次调用e
时都会5
- 生成结果e
。
为了证明右侧只是一个计数器,以下所有会产生5
的相同结果:
[5,5,5,5]