简体   繁体   English

用python中的列表对嵌套字典进行排序

[英]sorting a nested dictionary with lists in python

I am trying to sort a dictionary containing lists. 我正在尝试对包含列表的字典进行排序。 For example, if I have this dictionary: 例如,如果我有这个字典:

a = {'q': {3: [4, 2, 7]}, 'a': {1: [5, 45, 11]}, 'e': {23: [11, 45, 2]}}

I want the output after sorting to be: 我希望排序后的输出是:

[(e, {23:[11,45,2}]), (a, {1:[5,45,11]}), (q,{3,[4,2,7]})] 

I am actually sorting in reverse, using the first item in the list as the key for the sort. 我实际上是在反向排序,使用列表中的第一项作为排序的键。

In the event that the first items of two lists are identical, like above, I sort for the string associated with the list (main key) in alphabetical order. 如果两个列表的第一项相同,如上所述,我将按字母顺序对与列表(主键)关联的字符串进行排序。

I am not sure if I can get the output of tuples with dictionary in it as I am sorting for that the list in that dictionary. 我不确定是否可以在其中获取带有字典的元组的输出,因为我正在对该字典中的列表进行排序。

I have tried this code: 我已经试过这段代码:

sorted((x,b.items(), key=lambda x:[1][2]) for x,b in a.items())

It raised an error for invalid syntax, and I can't figure out what's wrong. 由于语法无效,它引发了一个错误,但我无法弄清楚出了什么问题。

Let's break the problem in parts. 让我们分部分解决这个问题。 You really want to sort the list a.items() . 您确实要对列表a.items()进行排序。 So: 所以:

>>> to_sort = a.items()
>>> to_sort
[('q', {3: [4, 2, 7]}), ('a', {1: [5, 3, 11]}), ('e', {23: [11, 45, 2]})]

Now, for each element in the list, you have a tuple of a value ( 'q' etc.) and a dictionary. 现在,对于列表中的每个元素,您都有一个值的元组( 'q'等)和一个字典。 Presumably, each dictionary contains only one key, and you want to use the index-1 element of each dictionary's value as the primary key. 假定每个字典仅包含一个键,并且您想将每个字典值的index-1元素用作主键。 So, the key for the first element should be: to_sort[0][1].values()[0][1] : to_sort[0][1] gives you the dictionary {3: [4, 2, 7]} , .values() gives you the list [[4, 2, 7]] , and [0][1] on that gives you 2 . 因此,第一个元素的键应为: to_sort[0][1].values()[0][1]to_sort[0][1]为您提供字典{3: [4, 2, 7]} to_sort[0][1] {3: [4, 2, 7]} .values()给出列表[[4, 2, 7]] .values() [[4, 2, 7]] ,而列表上的[0][1]给您2 The secondary sort key is simply to_sort[0] . 次要排序键只是to_sort[0]

So we get: 这样我们得到:

>>> sorted(to_sort, key=lambda x: (x[1].values()[0][1], x[0]))
[('q', {3: [4, 2, 7]}), ('a', {1: [5, 3, 11]}), ('e', {23: [11, 45, 2]})]

We are almost there. 我们就快到了。 Now you just need to tell sort that you want reversed output: 现在,您只需要告诉sort您想要反向输出:

>>> sorted(to_sort, key=lambda x: (x[1].values()[0][1], x[0]), reverse=True)
[('e', {23: [11, 45, 2]}), ('a', {1: [5, 3, 11]}), ('q', {3: [4, 2, 7]})]

Is this what you want? 这是你想要的吗?

If you want a one-liner, you can do: 如果您需要单线,则可以执行以下操作:

>>> sorted(a.items(), key=lambda x: (x[1].values()[0][1], x[0]), reverse=True)

At least in the interactive interpreter, the full error message should show you exactly where the error is happening: 至少在交互式解释器中,完整的错误消息应向您确切显示错误发生的位置:

>>> sorted((x,b.items(), key=lambda x:[1][2]) for x,b in a.items())
  File "<stdin>", line 1
    sorted((x,b.items(), key=lambda x:[1][2]) for x,b in a.items())
                            ^
SyntaxError: invalid syntax

Notice that the ^ is right below the = . 请注意, ^就在=正下方。

That doesn't tell you why you got an error there, but at least it tells you where to look. 但这并不能告诉您为什么在那里出错,但是至少可以告诉您在哪里看。

And once you look carefully, notice this sub-expression: 当您仔细查看后,请注意以下子表达式:

(x,b.items(), key=lambda x:[1][2])

So that's a tuple, whose third member is key=lambda x:[1][2] . 这是一个元组,其第三个成员是key=lambda x:[1][2] But that isn't valid as an expression. 但这作为表达式是无效的。 So, you've got some parentheses in the wrong place. 因此,您在错误的位置加上了括号。 Or, rather, you've added the key parameter to the wrong place. 或者,相反,您已将key参数添加到错误的位置。 I think you meant this: 我认为您的意思是:

sorted(((x,b.items()) for x,b in a.items()), key=lambda x:[1][2])

No SyntaxError there. 那里没有SyntaxError It looks like that's going to get an IndexError later on, but you can deal with that when you get there. 看起来稍后会收到IndexError ,但是到达那里后就可以解决。

I'm not 100% sure, but are you ultimately after? 我不确定100%,但是您最终会追求吗?

>>> a = {'q': {3: [4, 2, 7]}, 'a': {1: [5, 3, 11]}, 'e': {23: [11, 45, 2]}}
>>> new_order = sorted(a, key=lambda L: a[L].values(), reverse=True)
>>> zip(new_order, map(a.get, new_order))
[('e', {23: [11, 45, 2]}), ('a', {1: [5, 3, 11]}), ('q', {3: [4, 2, 7]})]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM