【发布时间】:2022-01-17 09:02:23
【问题描述】:
在下面的代码中,l1 得到 ([1], [1]),l2, l3, l4 得到 ([0], [1])。这让我感到惊讶,尤其是在 in 子句 (l3, l4) 中使用 t 之间的区别,无论是生成器理解还是列表理解,与 if 子句 (@987654329) 没有区别@),它在哪里。
l1 = [(x for x in (0, 1) if x == t) for t in (0, 1)]
l2 = [[x for x in (0, 1) if x == t] for t in (0, 1)]
l3 = [(x for x in [t]) for t in (0, 1)]
l4 = [[x for x in [t]] for t in (0, 1)]
print([(*map(list, l),) for l in (l1, l2, l3, l4)])
能否请您详细解释一下有关此类表达的规则?相关文档的链接?理由?
【问题讨论】:
-
我强烈建议不要编写依赖于这种语义的代码。
-
@KarlKnechtel,我无意中注意到它,解决了 2021 年代码出现的第 13 天。要听从您的建议,或对一组可取的做法发表我自己的明智意见,我需要清楚地了解发生了什么在。否则我什至不知道我什么时候要写一些你建议避免的东西。
-
来自已删除的答案(但可能有助于更好地理解):尝试任何其他列表:>>> l1 = [(x for x in (0, 1, 2) if x == t ) for t in (0, 1, 2)] >>> (*map(next, l1),) (2, 2, 2) 我的评论:当然是 (2, 2, 2),我的用例确实有更多的价值,我为这个问题提取了它的本质。你的回答也是我的第一个猜测,但它仍然不能解释 l1 和 l3 之间的区别。而 t 在每种情况下的确切范围仍然难以捉摸。
-
“否则我什至不知道我什么时候要写一些你建议避免的东西。”如果不需要,就不要关闭可变值?
-
@KarlKnechtel,它显然不是可变的,看不到赋值(简单或复合)运算符。如果您的意思是任何具有延迟评估的代码(包括生成器)都不应该引用可变变量(包括
for循环的控制变量,无论是在for语句中还是任何类型的理解中),那么它就很牵强限制。并不是我强烈反对你的建议,只是想权衡利弊;也许之后我会分享你的结论。但无论如何,对于这个问题,这是一个切题的讨论。
标签: python closures list-comprehension generator semantics