频率排序问题 python - sorted() 没有给出我所期望的

frequency sorting problem python - sorted() does not give what I would expect

我有这样的代码:

def frequency_sorting(numbers):
    return sorted(numbers, key=lambda i:numbers.count(i),reverse=True)

或者:

def frequency_sorting(numbers):
    return sorted(numbers, key=numbers.count,reverse=True)

当我打电话时:

frequency_sorting([3,4,11,13,11,4,4,7,3])

都给我:

[4, 4, 4, 3, 11, 11, 3, 13, 7]

我预计:

[4, 4, 4, 3, 3, 11, 11, 13, 7]

我知道如何解决最初的想法。我只需要从理论上理解为什么我的代码不起作用。

您的代码不起作用,因为 11 和 3(在您的示例中)具有相同的计数;相同的排序优先级。

所以 3, 11 是一个有序序列,就像 11, 33, 3, 11, 113, 11, 3, 11 一样都是正确的,选择取决于算法的实现方式。

所以你需要指定顺序的关键不仅仅是相等元素的数量,而是相等元素的数量(重要性更高)和元素本身(如果你想要这个)。因此,如果您想要相等元素数量的反向顺序和(然后)元素值的顺序,您可以使用:

sorted(numbers, key=lambda i:(-numbers.count(i),i))

或同样

sorted(numbers, key=lambda i:(numbers.count(i),-i),reverse=True)

您可能希望按元素数量和(然后)元素的首次出现顺序排列,在这种情况下,您可以使用:

sorted(numbers, key=lambda i:(-numbers.count(i),numbers.index(i)))

或者你可以用别的东西;这取决于你想如何对具有相同计数但不同值的元素进行排序

排序是guaranteed to be stable,就是说如果有些项目有相同的键值,则保留它们原来的顺序。

更容易看到字符串发生了什么并且没有倒序:

list(sorted(['zzz', 'aa', 'cc', 'bb', 'bbb', 'aaa'], key=len))
# ['aa', 'cc', 'bb', 'zzz', 'bbb', 'aaa']

所有长度为 2 的字符串按其原始顺序首先出现,然后是所有长度为 3 的字符串,也按其原始顺序。

在您的代码中,计数为 2 的值按此顺序依次为 3、11、11 和 3。因此,排序后它们将保持此顺序(按照您的要求反转,但看起来一样)。

如果你想按计数排序,然后按值排序(而不是按原始顺序),你必须明确说明:

def frequency_sorting(numbers):
    return sorted(numbers, key=lambda i:(numbers.count(i), -i), reverse=True)