嵌套/多列表理解或生成器表达式的用例。什么时候更优雅?

2024-04-27 17:16:57 发布

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

我有时会看到这样的事情:

(k for k in (j for j in (i for i in xrange(10))))

现在这真的使我的大脑弯曲,我宁愿它不是这样呈现的。

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

编辑:感谢您提供简化此操作的方法示例。其实不是我要的,我想知道有没有优雅的时候。


Tags: 方法in编辑示例for表达式用例事情
3条回答

在你的例子中,我可能会写为:

foos = (i for i in xrange(10))
bars = (j for j in foos)
bazs = (k for k in bars)

如果给出更具描述性的名称,我想这可能会非常清楚,我无法想象会有任何可测量的性能差异。

也许你想的更多的表达方式是:

(x for x in xs for xs in ys for ys in lst)

——事实上,这甚至都是无效的。你得把东西按顺序放好:

(x for ys in lst for xs in ys for x in xs)

我可能会这样写,作为一个快速的扁平化列表的方法,但总的来说,我认为你是在写:你通过少输入节省的时间通常是由你花在获得正确的生成器表达式上的额外时间来平衡的。

如果你担心一行代码太复杂,你可以将其拆分:

(k for k in 
    (j for j in 
        (i for i in xrange(10))))

我总是发现在Python中,行的连续性看起来有点奇怪,但这确实使我们更容易看到每个行的循环。因为额外的赋值/查找不会产生或破坏任何东西,所以您也可以这样编写:

gen1 = (i for i in xrange(10))
gen2 = (j for j in gen1)
gen3 = (k for k in gen2)

在实践中,我认为我从未将理解嵌套超过2层,在这一点上,它仍然很容易理解。

检查PEP 202这是向语言引入列表理解语法的地方。

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

  • 表格[。。。对于x。。。对于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.

如果你遇到这样的情况,你会发现它更优雅。不过,IMHO代码中的多个嵌套列表理解可能比嵌套for循环更不清楚,因为for循环很容易被可视化地解析。

相关问题 更多 >