我试图使用来自收集模块的Python计数器对列表中的一些值进行排序。但是当它
时会产生奇怪的结果>>> diff=["aaa","aa","a"]
>>> c=Counter(diff)
>>> sorted(c.items(), key = lambda x:x[1] , reverse=True)
[('aa', 1), ('a', 1), ('aaa', 1)]
>>> c.items()
[('aa', 1), ('a', 1), ('aaa', 1)]
输出很奇怪,因为它似乎已经洗牌了一个' aa'到了第一个地方,那么' a'和' aaa'最后。 理想情况下,应该是' a'然后' aa'然后' aaa'
这背后的原因是什么,你将如何纠正相同的
编辑: 大多数人都不正确地理解这个问题,因此我正在推动一些澄清。目标是根据列表的出现情况对列表中的单词数进行排序。
让我们说列表diff = ["this", "this", "world", "cool", "is", "cool", "cool"]
。我上面代码的最终输出是cool
然后this
然后is
然后world
这是正确的。
但问题是当你提供相同的出现次数相同的字符时,python行为异常。由于输入为diff = ["aaa", "aa", "a"]
,我预计输出为a
,然后是aa
,然后是aaa
。但是python算法永远不会知道每个单词都是单次出现的。
但如果是这样,那么为什么python没有打印aaa
然后aa
然后a
(即输入的顺序相同)给出了怀疑的好处。 Python排序确实交换了。为什么?
答案 0 :(得分:2)
Counter
是dict
的子类。这是一个无序的集合。
获得所需的排序顺序,您可以更新代码,如 -
sorted(c.items(), key = lambda x:(x[1], -len(x[0])) , reverse=True)
这给出了 -
[('a', 1), ('aa', 1), ('aaa', 1)]
答案 1 :(得分:1)
sorted
执行stable sort。这意味着对于关系,项目的顺序将与它们在原始输入中出现的顺序相同。由于Counter
无序,sorted
的输入处于某种未定义的顺序。如果需要,可以按键排序,然后输入值:
sorted(sorted(c.items(), key=lambda x:x[0], reverse=True), key = lambda x:x[1] , reverse=True)
或者(可能更好)让你的sort函数返回一个元组作为排序键:
sorted(c.items(), key=lambda x:(x[1], x[0]), reverse=True)
使用operator.itemgetter
的一个(甚至更好!)版本:
sorted(c.items(), key=itemgetter(1,0), reverse=True)
答案 2 :(得分:0)
这是您确保订购不变的一种方式。
如前所述,字典不被视为已订购。结果将是一个排序的元组列表。
except