python 如何在不从列表中删除元素的情况下按出现次数对列表进行排序?
python How do you sort list by occurrence with out removing elements from the list?
只是想知道如何在 python 2.7 中按 frequency/occurrence 对列表进行排序,如果 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]
再次感谢
您可以使用 collections
中的 Counter
class 作为排序键。由于您可能有多个出现次数相同的元素,您可以使用值本身作为辅助排序键,以便将相同的元素组合在一起:
>>> 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]
要进行这种排序,您需要找到第一个索引和每个项目的计数。我将使用一个函数来完成这两项操作,但还有其他方法:
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]
只是想知道如何在 python 2.7 中按 frequency/occurrence 对列表进行排序,如果 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] 再次感谢
您可以使用 collections
中的 Counter
class 作为排序键。由于您可能有多个出现次数相同的元素,您可以使用值本身作为辅助排序键,以便将相同的元素组合在一起:
>>> 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]
要进行这种排序,您需要找到第一个索引和每个项目的计数。我将使用一个函数来完成这两项操作,但还有其他方法:
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]