python如何按列表排序列表而不从列表中删除元素?

时间:2017-02-22 14:43:58

标签: python python-2.7 list sorting frequency

只是想知道如何按python 2.7中的频率/出现排序列表,如果2个元素出现的次数相同,那么原始列表中首先出现的元素位于新列表中另一个元素的前面。

例如:

list = [5,6,8,9,8,8,3,4,4,6,6]
sorted_list = [6,6,6,8,8,8,4,4,5,9,3]

知道为什么解决方案不适用于[1,3,3,3,2,2,2,1,1]。输出为[3,3,3,2,2,2,1] ,1,1]但正确的输出是[1,1,1,3,3,3,2,2,2] 再次感谢

2 个答案:

答案 0 :(得分:2)

您可以使用Counter中的collections类作为排序键。由于您可能有多个具有相同出现次数的元素,因此可以将值本身用作次要排序键,以便将相同的元素组合在一起:

>>> from collections import Counter
>>> lst = [5,6,8,9,8,8,3,4,4,6,6] 
>>> c = Counter(lst)
>>> sorted(lst, key = lambda x : (c[x], x), reverse = True)
[8, 8, 8, 6, 6, 6, 4, 4, 9, 5, 3]

编辑: 正如MSeifert评论的那样,关系应该按照首次出现的顺序而不是元素的价值来打破。这可以使用原始列表中的index函数来完成:

>>> sorted(lst, key = lambda x : (-1 * c[x], lst.index(x)))
[6, 6, 6, 8, 8, 8, 4, 4, 5, 9, 3]

答案 1 :(得分:2)

要进行这种排序,您需要找到第一个索引和每个项目的计数。我将使用一个函数来执行这两个功能,但还有其他方法:

def count_and_first_index(it):
    dct_counts = {}
    dct_first = {}
    for idx, item in enumerate(it):
        if item in dct_counts:
            dct_counts[item] += 1
        else:
            dct_counts[item] = 1
            dct_first[item] = idx

    return dct_counts, dct_first

然后使用key - 参数进行排序很简单:

>>> lst = [5,6,8,9,8,8,3,4,4,6,6]

>>> counts, firstidx = count_and_first_index(lst)

>>> sorted(lst, key=lambda x: (counts[x], -firstidx[x]), reverse=True)
[6, 6, 6, 8, 8, 8, 4, 4, 5, 9, 3]

我否定了index,因为它排序颠倒了,你想要第一个项目。不过,您也可以否定counts并删除reverse

>>> sorted(lst, key=lambda x: (-counts[x], firstidx[x]))
[6, 6, 6, 8, 8, 8, 4, 4, 5, 9, 3]