在Python中对嵌套字典和列表进行排序

0 投票
3 回答
3548 浏览
提问于 2025-04-17 14:54

我正在尝试对一个包含列表的字典进行排序。例如,如果我有这样的字典:

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

我希望排序后的输出是:

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

实际上,我是反向排序,使用列表中的第一个项目作为排序的依据。

如果两个列表的第一个项目相同,就像上面那样,我会根据与列表相关的字符串(主键)按字母顺序进行排序。

我不确定在对字典中的列表进行排序时,是否能得到包含字典的元组输出。

我尝试了这段代码:

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

但是它出现了语法错误,我搞不清楚哪里出了问题。

3 个回答

0

我不是百分之百确定,但你最终想要的是什么呢?

>>> 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]})]
1

至少在交互式解释器中,完整的错误信息会告诉你错误发生的具体位置:

>>> 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

注意到那个 ^ 是正好在 = 的下面。

这并不能告诉你为什么会在这里出错,但至少能告诉你该往哪里看。

仔细观察后,你会发现这个子表达式:

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

这是一个元组,它的第三个元素是 key=lambda x:[1][2]。但是,这个表达式是无效的。所以,你的括号放错地方了。或者说,你把 key 参数放错了位置。我想你应该是想这样:

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

那里没有 SyntaxError。看起来后面会出现一个 IndexError,但你可以等到那时候再处理。

2

我们把这个问题拆开来看。你其实是想对列表 a.items() 进行排序。那么:

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

对于列表中的每个元素,你会得到一个包含值(比如 'q' 等)和一个字典的元组。可以想象每个字典里只有一个键,而你想用每个字典值的第一个索引(也就是第二个元素)作为主要的排序依据。所以,第一个元素的排序关键字应该是: to_sort[0][1].values()[0][1]。这里 to_sort[0][1] 会给你字典 {3: [4, 2, 7]},而 .values() 会得到列表 [[4, 2, 7]],接着 [0][1] 就会得到 2。第二个排序关键字就是简单的 to_sort[0]

所以我们得到:

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

我们快完成了。现在你只需要告诉排序函数你想要反向输出:

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

这就是你想要的吗?

如果你想要一行代码搞定,可以这样写:

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

撰写回答