如何在不使用稳定排序的情况下使用 Python 对可迭代对象进行排序?

Tec*_*att 1 python sorting python-3.x

所以,我在 Input 中有一个像这样的可迭代对象:

[4, 6, 2, 2, 6, 4, 4, 4]
Run Code Online (Sandbox Code Playgroud)

我想根据降低的频率顺序对其进行排序。所以结果是这样的:

[4, 4, 4, 4, 6, 6, 2, 2]
Run Code Online (Sandbox Code Playgroud)

所以这里发生的事情是,当一个元素与另一个元素具有相同的频率时,它们将处于相同的顺序(6 首先出现,所以 6 在 2 之前)。

我尝试使用 sorted 函数来实现这种机制,但我遇到了一个大问题。

def frequency_sort(items):
    
    return sorted(items, key=lambda elem: sum([True for i in items if i == elem]), reverse=True)
Run Code Online (Sandbox Code Playgroud)

我知道这种简短的方法很难阅读,但它只是使用 key 参数对数组进行排序以提取数字的频率。但是,输出是这样的:

[4, 4, 4, 4, 6, 2, 2, 6]
Run Code Online (Sandbox Code Playgroud)

如您所见,输出与应有的输出略有不同。发生这种情况(我认为)是因为sorted()是一个执行“稳定排序”的函数,即如果有相同的键,排序将保持原样。

所以这里发生的事情就像一个强大的稳定排序。我想要更像是一种软排序,它会考虑顺序但会将相同的元素放在一起。

Dan*_*ejo 5

您可以使用collections.Counter并使用most_common它按频率降序返回:

from collections import Counter


def frequency_sorted(lst):
    counts = Counter(lst)
    return [k for k, v in counts.most_common() for _ in range(v)]


result = frequency_sorted([4, 6, 2, 2, 6, 4, 4, 4])
print(result)
Run Code Online (Sandbox Code Playgroud)

输出

[4, 4, 4, 4, 6, 6, 2, 2]
Run Code Online (Sandbox Code Playgroud)

most_common上的文档:

返回一个包含 n 个最常见元素及其从最常见到最少的计数的列表。如果省略 n 或 None,most_common() 返回计数器中的所有元素。具有相等计数的元素按第一次遇到的顺序排序

  • @TechMatt是的,第二个for循环位于第一个循环内,基本上两个值是元素(例如4)和计数(对于4 for 4的情况)。 (2认同)