按值排序计数器条目,然后按键排序

问题描述 投票:-3回答:3

我试图使用Python的Counter from collection模块在列表中排序一些值。但它给出了奇怪的结果

>>> 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排序确实交换了。为什么?

python python-2.7 sorting
3个回答
2
投票

Counterdict的子类。这是一个无序的集合。

得到你想要的排序顺序,你可以更新你的代码 -

sorted(c.items(), key = lambda x:(x[1], -len(x[0])) , reverse=True)

这给了 -

[('a', 1), ('aa', 1), ('aaa', 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)

0
投票

这是确保订单保持不变的一种方法。

如前所述,字典不被视为订购。结果将是元组的排序列表。

from collections import Counter

diff = ["aaa", "aa", "a"]

c = Counter(diff)

sorted(c.items(), key=lambda x: diff.index(x[0]))

# [('aaa', 1), ('aa', 1), ('a', 1)]
© www.soinside.com 2019 - 2024. All rights reserved.