在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中按值对嵌套字典进行排序,并按另一个值对余数进行排序的主要内容,如果未能解决你的问题,请参考以下文章