首页 > 解决方案 > 使用配对名称对嵌套字典进行排序

问题描述

我有以下格式的 Python 字典:

docs_info = {
  "6": {
    "031546386": {
      "o_name": "Michael",
      "n_name": "Palin"
    }
  },
  "2": {
    "020245492": {
      "o_name": "John",
      "n_name": "Cleese"
    }
  },
  "3": {
    "021027690": {
      "o_name": "Terry",
      "n_name": "Gilliam"
    },
    "040474564": {
      "o_name": "Terry",
      "n_name": "Jones"
    },
    "031336583": {
      "o_name": "Eric",
      "n_name": "Idle"
    }
  }
}

我想以特定格式显示它。

迭代应按数字升序使用键(以 开头"2",然后"3"等)。下一级字典的键是 id,应该按字母顺序排序,它的每个值都应该打印出o_namen_name值。

想要的最终结果应该是:

John Cleese
Terry Gilliam
Eric Idle
Terry Jones
Michael Palin

从之前的帖子中我了解到我们可以使用以下语法来获得第一次迭代:

for key, value in sorted(docs_info.items()):

但是我有一个问题要理解如何在嵌套的内部结构中进行迭代。

我该怎么做?

标签: pythonsorting

解决方案


只需在字典上添加另一个sorted()循环,与第一个循环相同:value

for key, value in sorted(docs_info.items()):
    for id, inner in sorted(lvl1.items()):
        print(inner["o_name"], inner["n_name"])

因为您不需要在循环中使用keyandid变量,所以最好使用它们的名称_,以表明您有意忽略它们。Python linter 将不会抱怨未使用该名称。

您可能还想为第二级字典使用不同的名称,而不是value,如果您想对键进行数字排序,则需要在排序时首先将这些键转换为整数:

for _, lvl1 in sorted(docs_info.items(), key=lambda kv: int(kv[0])):
    for _, inner in sorted(lvl1.items()):
        print(inner["o_name"], inner["n_name"])

演示:

>>> for _, lvl1 in sorted(docs_info.items(), key=lambda kv: int(kv[0])):
...     for _, inner in sorted(lvl1.items()):
...         print(inner["o_name"], inner["n_name"])
...
John Cleese
Terry Gilliam
Eric Idle
Terry Jones
Michael Palin

您可以将整个内容组合成一个列表理解:

sorted_names = [
    (inner["o_name"], inner["n_name"])
    for key, lvl1 in sorted(docs_info.items(), key=lambda kv: int(kv[0]))
    for id, inner in sorted(lvl1.items())
]

然而,对于未来的维护者来说,不使用上述结构可能不那么可读并且更加友好。


推荐阅读