扁平浅嵌套列表的习惯用法:它是如何工作的?

2024-06-28 11:19:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我在我正在处理的模块中发现了以下代码:

l = opaque_function()
thingys = [x for y in l for x in y]

我看不懂这个。通过实验,我能够确定它是扁平化一个2级嵌套列表,但是syntex对我来说仍然是不透明的。它显然省略了一些可选的括号。在

^{pr2}$

我的眼睛想把它解析为:[x for y in [l for x in y] ][ [x for y in l] for x in y ],但是这两个都失败了,因为y没有被定义。在

我该怎么读这个?在

(我想当我解释这件事的时候我会感到很尴尬。)


Tags: 模块代码in列表for定义function括号
3条回答

你应该这样读:

for y in l:
    for x in y:
        yield x

这是生成器版本,但是所有的理解都有相同的基本语法:当x放在前面时,表达式的其余部分仍然从左到右读取。一开始我也被这弄糊涂了,以为它会反过来,但一旦添加了过滤表达式,这就有意义了:

^{pr2}$

现在想象一下,把这整件事都写反了:

[x if isinstance(x, int)
   for x in y
   if len(y) < 4
   for y in l]

这甚至会让资深的Prolog程序员感到困惑,更不用说维护Python解析器的人了:)

当前的语法也与Haskell中的语法相匹配,这首先启发了列表理解。在

来自list displays文档:

When a list comprehension is supplied, it consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new list are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached.

因此,您的表达式可以重写为:

thingys = []
for y in l:
    for x in y:
        thingys.append(x)

这曾经让我很困惑。你应该像一个嵌套的循环一样阅读它:

new_list = []
for y in l:
    for x in y:
        new_list.append(x)

变成

^{pr2}$

变成

[x for y in l for x in y]

相关问题 更多 >