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

Posted

技术标签:

【中文标题】在Python中按值对嵌套字典进行排序,并按另一个值对余数进行排序【英文标题】:Sort nested dictionary by value, and remainder by another value, in Python 【发布时间】:2011-05-05 20:53:19 【问题描述】:

考虑这种字典格式。

'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 按任一值对列表进行排序,但如何也按第二个值排序?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

非常好的线路!以下是颠倒排序顺序的方法:只需将reverse=True 作为参数添加到sorted 函数的末尾即可。谢谢 改成上面那个。 your_list = sorted(your_dict, key=lambda x: (your_dict[x]['downloads'], your_dict[x]['date'])) 嗨,我在调用 sorted(d.items(), key=lambda x: (d[x]['downloads'], d[x]['date'])) 时收到错误 TypeError: unhashable type: 'dict',其中 d 等于 OP 中的字典。如果有人知道问题,请告诉我。谢谢 @ChickenFeet 使用 d.keys() 而不是 d.items() 这只是返回键,有没有办法获取键和您排序的项目?例如,有没有办法做到sorted((d.keys(), lambda y: d[y]['downloads']), key=lambda x: (d[x]['downloads']) 实际上是正确的?该代码原样向我抛出相同的 TypeError @ChickenFeet 得到【参考方案2】:

您可以将key 函数传递给sorted,它会返回一个包含您希望排序的两件事的元组。假设你的大字典叫d

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

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

如果您愿意,可以使用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"]

【讨论】:

我都试过了,但是我得到的不是一个键列表,而是一个元组列表。我也可以使用它,但它是不必要的复杂性。 [('KEY3','name':'python','date':20100710,'downloads':100)] @user479870 您可以使用[x[0] for x in items] 从元组中获取密钥。【参考方案3】:

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

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 answer 的最后一部分是最好的。

【讨论】:

呃,你为什么import-ing operator 然后从不使用它? @Amber 因为我以为我要做点别的事情,然后开始下雨了。我很着急。现在在里面。 未经测试。为什么在第一个 lambda x: 之后有两个 outer_dict[key]['downloads'] 的元组?【参考方案4】:
your_dict = dict(sorted(your_dict.items(), key = lambda x: (x[1]["downloads"], x[1]["date"])))

【讨论】:

虽然这个答案可能会回答这个问题,但如果您稍微解释一下代码会很好,例如为什么它是这样构建的,它是如何工作的等等。【参考方案5】:
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']))

【讨论】:

z.sort(key=lambda x: (x[1]['downloads'], x[1]['date'])) 返回无。知道为什么吗?

以上是关于在Python中按值对嵌套字典进行排序,并按另一个值对余数进行排序的主要内容,如果未能解决你的问题,请参考以下文章

在python中按值对defaultdict进行排序

如何按值对 Python 字典进行排序? [复制]

如何在 JavaScript 中按值对地图进行排序?

按值对字典进行排序[重复]

如何在PHP中按值对对象数组进行排序

我有不同的类,我想用这些类中的对象制作一个向量并按值对其进行排序