简体   繁体   English

为什么我的按频率排序列表的代码不起作用?

[英]Why doesn't my code for sorting list by frequency work?

I was trying to sort a list of number by their frequency, but when I try asserting, it didn't work.我试图按频率对数字列表进行排序,但是当我尝试断言时,它没有用。

So here is my code:所以这是我的代码:

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

And here is the assert that doesn't work这是不起作用的断言

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

When I tried directly with the value the output was as follow:当我直接尝试使用该值时,输出如下:

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

I tried looking at others solution and I found the following that worked:我尝试查看其他解决方案,发现以下方法有效:

sorted(sorted(numbers), key=numbers.count, reverse=True)

Why does this work and not my code?为什么这有效而不是我的代码? What is the difference between the 2 codes? 2个代码有什么区别? I don't understand why the first one doesn't work.我不明白为什么第一个不起作用。

11 and 3 are both present twice, and your sorting function doesn't give a way to break ties. 113都出现了两次,您的排序功能无法打破平局。 Since Python's sorting is stable, if A comes before B in the input list, and A and B have the same comparison key, A will also come before B in the output of sorted .由于 Python 的排序是稳定的,如果 A 在输入列表中排在 B 之前,并且 A 和 B 具有相同的比较键,那么在sorted的输出中 A 也排在 B 之前。

In your case, sorting the list before passing it to frequency_sorting orders your list numerically.在您的情况下,在将列表传递给frequency_sorting之前对列表进行排序,以数字方式对您的列表进行排序。 And since sorting is stable, when you run that list through your frequency_sorting function, the result will still be in order.由于排序是稳定的,当您通过frequency_sorting函数运行列表时,结果仍然是有序的。

If you want to do this more efficiently, you can use Counter to count your numbers with a O(n) algorithm.如果您想更有效地执行此操作,可以使用Counter使用 O(n) 算法计算您的数字。 Sorting and list extension are not O(1), but they're still more efficient than running numbers.count on every number in the list.排序和列表扩展不是O(1),但它们仍然比对列表中的每个数字运行numbers.count更有效。

from collections import Counter

def frequency_sorting(numbers):
    counted = Counter(sorted(numbers))

    result = []
    for number, count in counted.most_common():
        result.extend([number] * count)

    return result

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

What sorted does in internally sort the list according to the key specified sorted 在内部根据指定的键对列表进行排序

so essentially sorted(numbers,key=numbers.count,reverse=True)所以基本上排序(数字,键=数字。计数,反向=真)

This is trying to not sort这是试图不排序

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

but actually sort但实际上排序

[numbers.count(x) for x in numbers]
>>[2, 3, 2, 1, 2, 3, 3, 1, 2]

where 2 corresponds to both 11 and 3, so sort doesn't care if the original value was 11 or 3 as long as this array gets sorted其中 2 对应于 11 和 3,所以只要这个数组被排序,排序不关心原始值是 11 还是 3

[EDIT] [编辑]

Hence the solution that works using sorted would be using sorted twice因此,使用 sorted 的解决方案将使用 sorted 两次

sorted(sorted(numbers), key=numbers.count, reverse=True)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM