python 2奇怪的列表理解行为

时间:2015-08-04 23:00:48

标签: python list-comprehension

我正在查看列表理解,看到smth奇怪。 代码:

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')]

这种行为的原因是什么?

2 个答案:

答案 0 :(得分:12)

当您在this.getClass().getResourceAsStream("/file.txt"); 对象上调用list()时,会耗尽该对象。由于您执行此操作两次,因此第二个实例的长度为0。

首先:

itertools._grouper

现在已经筋疲力尽了。然后:

if len(list(g))

长度为0。

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

list

答案 1 :(得分:4)

您需要确保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(以检查长度),而不会消耗结果。

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