【问题标题】:python 2 strange list comprehension behaviourpython 2奇怪的列表理解行为
【发布时间】:2015-10-27 12:52:35
【问题描述】:

我环顾列表理解,发现有些奇怪。 代码:

a = ['a', 'a', 'a', 'b', 'd', 'd', 'c', 'c', 'c']
print [(len(list(g)), k) if len(list(g)) > 1 else k for k, g in groupby(a)]

结果:

[(0, 'a'), 'b', (0, 'd'), (0, 'c')]

但我想看看:

[(3, 'a'), 'b', (2, 'd'), (3, 'c')]

这种行为的原因是什么?

【问题讨论】:

    标签: python list-comprehension


    【解决方案1】:

    当您在 itertools._grouper 对象上调用 list() 时,您会耗尽该对象。由于您这样做了两次,因此第二个实例的长度为 0。

    第一:

    if len(list(g))
    

    现在已经筋疲力尽了。那么:

    (len(list(g)), k))
    

    长度为 0。

    您可以在list 理解中嵌套生成器/理解,以在处理对象之前耗尽对象并保存相关数据:

    >>> [(y,x) if y>1 else x for x,y in ((k, len(list(g))) for k, g in groupby(a))]
    [(3, 'a'), 'b', (2, 'd'), (3, 'c')]
    

    【讨论】:

      【解决方案2】:

      您需要确保g 的元素只被消费一次:

      >>> print [(len(list(g)), k) if len(list(g)) > 1 else k for k, g in ((k, list(g)) for k, g in groupby(a))]
      [(3, 'a'), 'b', (2, 'd'), (3, 'c')]
      

      此代码还将遍历 k, g in groupby(a),但会将 g 转换为列表对象。然后,其余代码可以根据需要多次访问g(以检查长度),而不会消耗结果。

      在进行此更改之前,g 是一个 itertools._grouper 对象,这意味着您只能迭代 g 一次。之后它将为空,您将无法再次对其进行迭代。这就是您在结果中看到长度 0 的原因。

      【讨论】:

        猜你喜欢
        • 2013-12-28
        • 1970-01-01
        • 2013-03-26
        • 1970-01-01
        • 1970-01-01
        • 2011-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多