在 Python 中按值对嵌套字典进行排序,并按另一个值进行余数排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4110665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:18:01  来源:igfitidea点击:

Sort nested dictionary by value, and remainder by another value, in Python

pythonsortingdictionarypython-2.5

提问by

Consider this dictionary format.

考虑这种字典格式。

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

I'd like the dictionary sorted by downloads first, and then all items with no downloads sorted by date. Obviously a dictionary cannot be sorted, I just need a sorted listed of keys I can iterate over.

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

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

I can already sort the list by either value using sorted, but how do I sort by second value too?

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

采纳答案by Amber

Use the keyargument for sorted(). It lets you specify a function that, given the actual item being sorted, returns a value that should be sorted by. If this value is a tuple, then it sorts like tuples sort - by the first value, and then by the second value.

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

sorted(your_list, key=lambda x: (your_dict[x]['downloads'], your_dict[x]['date']))

回答by mouad

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']))

回答by aaronasterling

My other answer was wrong (as are most of the answers here)

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

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'])

This will create a list with the items that have been downloaded sorted in descending order at the front of it and the rest of the items that have not been downloaded sorted by date after those that have.

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

But actually, the last part of Eli Courtwrights answeris the best.

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

回答by Eli Courtwright

You can pass a keyfunction to sortedwhich returns a tuple containing the two things you wish to sort on. Assuming that your big dictionary is called d:

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

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

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

You can do this with a lambdaif you prefer, but this is probably more clear. Here's the equivalent lambda-based code:

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

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

Incidentally, since you mentioned that you wanted to sort by "downloads" first, the above two examples sort according to download counts in ascending order. However, from context it sounds like you might want to sort in decreasing order of downloads, in which case you'd say

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

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

in your keyfunc. If you wanted something like sorting in ascending order for non-zero download numbers, then having all zero-download records after that, you could say something like

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

return (-d["downloads"] or sys.maxint), d["date"]