2014-10-17 42 views
-3

喜的Python用户,Python中的集合模块行为奇怪吗?

我不是100%肯定,但它似乎有在蟒蛇的错误功能collections.Counter()这是collections模块中的一部分。函数collections.Counter()应计算列表中数字的出现次数,换句话说,它应该确定列表(矢量)中数字的出现频率。如果这些数字是浮点数或整数,这应该不重要。在很多场合它正常但不是做这项工作始终,这里是当它不能给出正确答案的例子:

import numpy as np 
from itertools import groupby 
import collections 
import matplotlib.pyplot as plt 

data_1=[250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 254] 
data_2=[250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 254, 255, 256, 256] 

# Determine no. of repetitions for the sweeped wavelengths 
d2=collections.Counter(data_1) # BUG in the collections module for data_2 but NOT for data_1 
d3=d2.values() 

print d3 

data_1名单上使用collections.Counter将给出正确的答案(D3)的所有事件:

[2, 4, 4, 4, 5] 

但是,如果我在data_2申请collections.Counter我得到以下答案(D3):

[2, 2, 4, 4, 4, 5, 1] 

这是WR翁。它应该是[2, 4, 4, 4, 5, 1, 2]。看起来像collections.Counter()交换了一些元素,但我找不到任何合理的解释,为什么它这样做。顺便说一句。我正在使用Python 2.7.5

对此有什么意见?

PS1:字典功能dict((i,data_2.count(i)) for i in data_2)对于data_2给出与collections.Counter(data_2)相同的错误答案。

PS2:该解决似乎是从itertools模块groupby功能:

from itertools import groupby 
d3=[len(list(group)) for key, group in groupby(data_2)] 
+3

道德:总是假设的错误更可能是你的比你正在使用的语言。 – 2014-10-17 14:45:32

+0

感谢您的评论凯文:-) data_2.count()函数工作正常,但字典似乎随机命令输出元素和尊重值,如你所说。 – Commi 2014-10-17 14:51:07

+0

亲爱的零比雷埃夫斯,我没有犯错。尝试编译我的代码并查看。 – Commi 2014-10-17 14:54:43

回答

2

collections.Counterdict的亚型。字典没有订单。因此,您在Counter对象(字典!)上使用d.values()的输出是任意的,可能不是您想要的。

如果您想订购您通过密钥得到的值,你应该重点首先值进行排序,然后返回值:

>>> [v for k, v in sorted(Counter(data_1).items(), key=lambda x: x[0])] 
[2, 4, 4, 4, 5] 
>>> [v for k, v in sorted(Counter(data_2).items(), key=lambda x: x[0])] 
[2, 4, 4, 4, 5, 1, 2] 
+0

祝福你打个招呼:-)使用集合的人有很多例子。计数器()用于数字计数,无需排序。你是顶尖的:-) – Commi 2014-10-17 14:58:55

2

在字典中的项目顺序是具体实施的行为。计数器可以按照自己想要的顺序排列键值对。这是按预期工作的。

按照official documentation

键和值遍历在非随机的,不同的Python实现不同而不同,取决于插入和删除的字典的历史以任意顺序。