代码之家  ›  专栏  ›  技术社区  ›  Ali Afshar

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

  •  11
  • Ali Afshar  · 技术社区  · 17 年前

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

    是否有使用过这些嵌套表达式的用例或示例,它们比嵌套循环更优雅、更可读?

    编辑: 感谢您提供的简化方法示例。这并不是我想要的,我想知道是否有过优雅的时候。

    7 回复  |  直到 17 年前
        1
  •  21
  •   popcnt    17 年前

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

    • 表单[…对于x…对于y…]嵌套,带有最后一个索引

    同样来自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

        2
  •  15
  •   Soviut    17 年前

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

    (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个深度的理解,在这一点上它仍然很容易理解。

        3
  •  6
  •   John Fouhy    17 年前

    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)
    

    我可能会这样写,作为一种快速平展列表的方法,但总的来说,我认为您是在写:您通过减少键入来节省的时间通常与您为正确使用生成器表达式所花费的额外时间相平衡。

        4
  •  4
  •   Jeremy Cantrell    17 年前

    因为它们是生成器表达式,所以可以将它们绑定到各自的名称,以使其更可读,而不会改变性能。将其更改为嵌套循环可能会损害性能。

    irange = (i for i in xrange(10))
    jrange = (j for j in irange)
    krange = (k for k in jrange)
    

    选择哪一个并不重要,我认为多行示例总体上更具可读性。

        5
  •  1
  •   NaturalLinguist    10 年前

    注意:优雅在一定程度上取决于品味。

    清单的理解永远不会再多了 清楚的 强大的 而不是列出理解。那么,为什么要使用它们呢?

    列表理解是什么 简明的 --它们允许你在一行中做一些事情。

    使用列表理解的时机是,当您需要某个列表时,可以相当轻松地动态创建它,并且您不希望或不需要中间对象。当您需要将当前作用域中的某些对象打包为一个可以馈送到函数中的对象时,可能会发生这种情况,如下所示:

    list1 = ['foo', 'bar']
    list2 = ['-ness', '-ity']
    return filterRealWords([str1+str2 for str1 in list1 for str2 in list2])
    

    这段代码的可读性与扩展版本差不多,但要短得多。它避免了创建/命名在当前范围内只使用一次的对象,这可以说是更优雅的。

        6
  •  0
  •   jfs    17 年前

    表达方式:

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

    (i for i in xrange(10))
    

    这几乎是一样的:

    xrange(10)
    

        7
  •  0
  •   Leinad177    12 年前

    我发现它在这样的情况下非常有用和优雅,因为您有这样的代码:

    output = []
    for item in list:
        if item >= 1:
            new = item += 1
            output.append(new)
    

    output = [item += 1 for item in list if item >= 1]