嵌套/多列表推导或生成器表达式的用例.什么时候更优雅?

Ali*_*har 12 python list-comprehension generator-expression

我有时会看到这种事:

(k for k in (j for j in (i for i in xrange(10))))
Run Code Online (Sandbox Code Playgroud)

现在这真的让我的大脑弯曲了,我宁愿不以这种方式呈现.

是否有任何用例,或使用这些嵌套表达式的例子,它比嵌套循环更优雅,更可读?

编辑:感谢您简化此方法的示例.这实际上并不是我要求的,我想知道是否有任何优雅的时刻.

pop*_*cnt 19

检查PEP 202,其中列表推导语法被引入该语言.

为了理解你的例子,Guido自己有一个简单的规则:

  • 形式[... for x ... for y ...]嵌套,最后一个索引变化最快,就像嵌套for循环一样.

同样来自PEP 202,用于回答您的问题:

Rationale
    List comprehensions provide a more concise way to create lists in
    situations where map() and filter() and/or nested loops would
    currently be used.

如果你有这样的情况,你会发现它更优雅.但是,恕我直言,您的代码中的多个嵌套列表推导可能不如嵌套for循环更清晰,因为for循环很容易在视觉上解析.


DNS*_*DNS 14

如果你担心一行上的复杂程度太高,你可以拆分它:

(k for k in 
    (j for j in 
        (i for i in xrange(10))))
Run Code Online (Sandbox Code Playgroud)

我总是发现行继续在Python中看起来有些奇怪,但这确实可以更容易地看到每个循环的内容.由于额外的赋值/查找不会产生或破坏任何东西,你也可以这样写:

gen1 = (i for i in xrange(10))
gen2 = (j for j in gen1)
gen3 = (k for k in gen2)
Run Code Online (Sandbox Code Playgroud)

在实践中,我认为我没有嵌套超过2深的理解,在那时它仍然很容易理解.


Joh*_*uhy 5

在你的例子中,我可能会把它写成:

foos = (i for i in xrange(10))
bars = (j for j in foos)
bazs = (k for k in bars)
Run Code Online (Sandbox Code Playgroud)

鉴于更具描述性的名称,我认为这可能非常清楚,我无法想象存在任何可衡量的性能差异.

也许你正在考虑更多的表达方式:

(x for x in xs for xs in ys for ys in lst)
Run Code Online (Sandbox Code Playgroud)

- 实际上,这甚至都没有效.你必须按其他顺序放置东西:

(x for ys in lst for xs in ys for x in xs)
Run Code Online (Sandbox Code Playgroud)

我可能会把它写成一个扁平化列表的快速方法,但总的来说我认为你写的是:通过输入less来节省的时间通常可以通过你花费额外的时间来获得生成器表达式来平衡.