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

时间:2010-11-05 22:35:39

标签: python sorting dictionary python-2.5

考虑这种字典格式。

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

5 个答案:

答案 0 :(得分:39)

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

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

答案 1 :(得分:8)

您可以将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"]

答案 2 :(得分: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 answer的最后一部分是最好的。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

your_dict = dict(sorted(your_dict.items(), key = lambda x: (x[1]["downloads"], x[1]["date"])))