44

考虑这种字典格式。

{'KEY1':{'name':'google','date':20100701,'downloads':0},
 'KEY2':{'name':'chrome','date':20071010,'downloads':0},
 'KEY3':{'name':'python','date':20100710,'downloads':100}}

我希望字典首先按下载排序,然后所有没有下载的项目按日期排序。显然字典无法排序,我只需要一个可以迭代的键的排序列表。

['KEY3','KEY1','KEY2']

我已经可以使用任何一个值对列表进行排序sorted,但是如何也按第二个值排序呢?

4

5 回答 5

61

使用 的key参数sorted()。它允许您指定一个函数,在给定实际排序的项目的情况下,返回一个应该排序的值。如果这个值是一个元组,那么它的排序就像元组排序一样——先按第一个值,然后再按第二个值。

sorted(your_list, key=lambda x: (your_dict[x]['downloads'], your_dict[x]['date']))
于 2010-11-05T22:43:14.987 回答
18

您可以传递一个key函数,sorted该函数返回一个包含您希望排序的两件事的元组。假设您的大字典被称为d

def keyfunc(tup):
    key, d = tup
    return d["downloads"], d["date"]

items = sorted(d.items(), key = keyfunc)

如果您愿意,可以使用 a 来执行此操作lambda,但这可能更清楚。这是等效的基于 lambda 的代码:

items = sorted(d.items(), key = lambda tup: (tup[1]["downloads"], tup[1]["date"]))

顺便说一句,由于您提到要先按“下载”排序,所以上面的两个示例按照下载次数升序排序。但是,从上下文来看,您可能希望按下载的降序排序,在这种情况下,您会说

return -d["downloads"], d["date"]

在你的keyfunc. 如果您想要按升序对非零下载数进行排序,然后在此之后拥有所有零下载记录,您可以这样说

return (-d["downloads"] or sys.maxint), d["date"]
于 2010-11-05T22:42:47.807 回答
2

我的另一个答案是错误的(就像这里的大多数答案一样)

sorted_keys = sorted((key for key in outer_dict if outer_dict[key]['downloads']),
                     key=lambda x: (outer_dict[key]['downloads'],
                                    outer_dict[key]['downloads'])
                     reverse=True)

sorted_keys += sorted((key for key in outer_dict if not outer_dict[key]['downloads']),
                      key=lambda x: outer_dict[key]['date'])

这将创建一个列表,其中已下载的项目按降序排列在其前面,其余未下载的项目按日期排序在已下载的项目之后。

但实际上, Eli Courtwrights 答案的最后一部分是最好的。

于 2010-11-05T22:42:39.177 回答
2
your_dict = dict(sorted(your_dict.items(), key = lambda x: (x[1]["downloads"], x[1]["date"])))
于 2021-05-21T03:15:54.460 回答
1
a = {'KEY1':{'name':'google','date':20100701,'downloads':0},
 'KEY2':{'name':'chrome','date':20071010,'downloads':0},
 'KEY3':{'name':'python','date':20100710,'downloads':100}}


z = a.items()

z.sort(key=lambda x: (x[1]['downloads'], x[1]['date']))
于 2010-11-05T22:42:17.767 回答