一尘不染

python字典基于值降序排序

python

我想根据子键key3的值按降序对字典d进行排序。见下文:

d = { '123': { 'key1': 3, 'key2': 11, 'key3': 3 },
      '124': { 'key1': 6, 'key2': 56, 'key3': 6 },
      '125': { 'key1': 7, 'key2': 44, 'key3': 9 },
    }

所以最终的字典看起来像这样。

d = { '125': { 'key1': 7, 'key2': 44, 'key3': 9 },
      '124': { 'key1': 6, 'key2': 56, 'key3': 6 },
      '123': { 'key1': 3, 'key2': 11, 'key3': 3 },
    }

我的方法是从d形成另一个字典e,其字典键将是key3的值,然后使用reversed(sorted(e)),但是由于key3的值可以相同,因此字典e丢失了一些键及其值。说得通?

我怎样才能做到这一点?这不是经过测试的代码。我只是想了解逻辑。


阅读 375

收藏
2021-01-20

共1个答案

一尘不染

字典没有任何固有的顺序。或者,相反,它们的固有顺序是“任意但不是随机的”,因此对您没有任何好处。

用不同的术语来说,您d和您e将是完全等效的字典。

您可以在此处使用OrderedDict

from collections import OrderedDict
d = { '123': { 'key1': 3, 'key2': 11, 'key3': 3 },
      '124': { 'key1': 6, 'key2': 56, 'key3': 6 },
      '125': { 'key1': 7, 'key2': 44, 'key3': 9 },
    }
d_ascending = OrderedDict(sorted(d.items(), key=lambda kv: kv[1]['key3']))
d_descending = OrderedDict(sorted(d.items(), 
                                  key=lambda kv: kv[1]['key3'], reverse=True))

原始文件d具有任意顺序。d_ascending具有您原先 认为 的顺序d,但没有。并d_descending拥有您想要的订单e


如果您实际上并不需要e用作字典,而只是希望能够以d特定顺序迭代的元素,则可以简化此操作:

for key, value in sorted(d.items(), key=lambda kv: kv[1]['key3'], reverse=True):
    do_something_with(key, value)

如果要在所有更改中以排序的顺序维护词典,而不是OrderedDict,则需要某种排序的词典。您可以在PyPI上找到许多选项,一些选项在树的顶部实现,其他选项在OrderedDict按需要重新排序的顶部等等。

2021-01-20