簡體   English   中英

按值(列表)對字典應用功能對其排序

[英]Sort a dictionary by value(list) applying function to it

我有一本字典:

students = {
    '1': [32, 14, 31, 23],
    '2': [32, 8, 36.5, 22],
    '3': [26, 11, 39, 15.5],
    '4': [34, 15, 44, 25],
    '5': [30, 6, 25, 24],
    '6': [26, 8, 31, 13],
    '7': [24, 4, 16, 17],
    '8': [22, 2, 0, 11.2],
    '9': [22, 4, 15, 10],
    '10': [31, 4, 16, 4.2],
    '11': [18, 3.5, 0, 0],
    '12': [28, 5, 30, 18.5],
    '13': [34, 13, 23, 13],
}

我想按每個列表的總和對字典進行排序。 所以我可以這樣:

import operator

students = {
    '1': sum([32, 14, 31, 23]),
    '2': sum([32, 8, 36.5, 22]),
    '3': sum([26, 11, 39, 15.5]),
    '4': sum([34, 15, 44, 25]),
    '5': sum([30, 6, 25, 24]),
    '6': sum([26, 8, 31, 13]),
    '7': sum([24, 4, 16, 17]),
    '8': sum([22, 2, 0, 11.2]),
    '9': sum([22, 4, 15, 10]),
    '10': sum([31, 4, 16, 4.2]),
    '11': sum([18, 3.5, 0, 0]),
    '12': sum([28, 5, 30, 18.5]),
    '13': sum([34, 13, 23, 13]),
}

sorted_students = sorted(
    students.items(), key=operator.itemgetter(1), reverse=True)

但:

  1. 我不想更改字典,我想將列表作為值
  2. 我不想寫多次sum()

我嘗試了key=sum(operator.itemgetter(1))但是很明顯它不起作用,我得到了:

TypeError: 'operator.itemgetter' object is not iterable

有什么更有效的方式來做我想做的事?

字典未排序,因此無法對字典進行“排序”。 但是,如果需要一個單獨的已排序鍵列表,則可以這樣做:

>>> students = {
    '1': [32, 14, 31, 23],
    '2': [32, 8, 36.5, 22],
    '3': [26, 11, 39, 15.5],
    '4': [34, 15, 44, 25],
    '5': [30, 6, 25, 24],
    '6': [26, 8, 31, 13],
    '7': [24, 4, 16, 17],
    '8': [22, 2, 0, 11.2],
    '9': [22, 4, 15, 10],
    '10': [31, 4, 16, 4.2],
    '11': [18, 3.5, 0, 0],
    '12': [28, 5, 30, 18.5],
    '13': [34, 13, 23, 13],
}
>>> sortedKeys = sorted(students.keys(), key = lambda x: sum(students[x]))
>>> sortedKeys
['11', '8', '9', '10', '7', '6', '12', '13', '5', '3', '2', '1', '4']

那么你可以遍歷列表,你會通過遍歷dict ,因為iter(dict)通過對按鍵進行迭代dict反正。

>>> for key in sortedKeys:
    print(key,sum(students[key]))


11 21.5
8 35.2
9 51
10 55.2
7 61
6 78
12 81.5
13 83
5 85
3 91.5
2 98.5
1 100
4 118

它們的鍵必須是可操作的,因此您需要將操作包裝在一個函數中:

key = lambda x: sum(x[1])

如果要基於最高總和訂購,請在按總和排序后使用OrderedDict

from collections import OrderedDict

students = OrderedDict(sorted(students.items(),key=lambda x: sum(x[1])))


OrderedDict([('11', [18, 3.5, 0, 0]), ('8', [22, 2, 0, 11.2]),
           ('9', [22, 4, 15, 10]), ('10', [31, 4, 16, 4.2]), 
           ('7', [24, 4, 16, 17]), ('6', [26, 8, 31, 13]),
          ('12', [28, 5, 30, 18.5]), ('13', [34, 13, 23, 13]), 
          ('5', [30, 6, 25, 24]), ('3', [26, 11, 39, 15.5]), 
          ('2', [32, 8, 36.5, 22]), ('1', [32, 14, 31, 23]), 
         ('4', [34, 15, 44, 25])])

如果要從最高和最低sorted ,請在sorted使用-sum(...

students = OrderedDict(sorted(students.items(),key=lambda x: -sum(x[1])))

print(students)
OrderedDict([('4', [34, 15, 44, 25]), ('1', [32, 14, 31, 23]),
        ('2', [32, 8, 36.5, 22]), ('3', [26, 11, 39, 15.5]), 
        ('5', [30, 6, 25, 24]), ('13', [34, 13, 23, 13]), 
        ('12', [28, 5, 30, 18.5]), ('6', [26, 8, 31, 13]),
        ('7', [24, 4, 16, 17]), ('10', [31, 4, 16, 4.2]), 
        ('9', [22, 4, 15, 10]), ('8', [22, 2, 0, 11.2]), 
        ('11', [18, 3.5, 0, 0])])

由於無法對字典進行排序,因此我們只能得到排序后的字典的表示形式,該字典將是一個列表,實際上是一個元組列表。

d = {k: sum(i for i in v) for k,v in students.items()}
print (sorted(d.items(), key=operator.itemgetter(1)))

輸出:

[('11', 21.5), ('8', 35.2), ('9', 51), ('10', 55.2), ('7', 61), ('6', 78), ('12', 81.5), ('13', 83), ('5', 85), ('3', 91.5), ('2', 98.5), ('1', 100), ('4', 118)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM