在Python 3中操作嵌套字典/列表树

时间:2015-09-06 09:56:10

标签: python loops python-3.x dictionary iterator

我正在尝试使用pandoc的JSON AST格式。

它像这样格式化。

[
  {
    "unMeta": {
      "date": {
        "t": "MetaInlines", "c": [
          {"t": "Str", "c": "2015-08-23"}]},
      "version": {
        "t": "MetaString",  "c": "0.22"},
      "author": {
        "t": "MetaInlines", "c": [
          {"t": "Str", "c": "John"},
          {"t": "Space", "c": []},
          {"t": "Str", "c": "MacFarlane"}]},
      "title": {
        "t": "MetaInlines", "c": [
          {"t": "Str", "c": "CommonMark"},
          {"t": "Space", "c": []},
          {"t": "Str", "c": "Spec"}]},
      "license": {
        "t": "MetaInlines", "c": [
          {"t": "Link", "c": [
            [
              {"t": "Str", "c": "CC-BY-SA"},
              {"t": "Space", "c": []},
              {"t": "Str", "c": "4.0"}
            ],
            ["http://creativecommons.org/licenses/by-sa/4.0/", ""]]
          }
        ]
      }
    }
  },
  [
    {"t": "Header", "c": [1, ["introduction", [], []], [
      {"t": "Str", "c": "Introduction"}]]},
    {"t": "Header", "c": [2, ["what-is-markdown", [], []], [
      {"t": "Str", "c": "What"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "is"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "Markdown?"}]]},
    {"t": "Para", "c": [
      {"t": "Str", "c": "Markdown"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "is"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "a"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "plain"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "text"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "format"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "for"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "writing"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "structured"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "documents,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "based"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "on"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "conventions"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "used"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "for"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "indicating"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "formatting"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "email"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "and"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "usenet"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "posts."},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "It"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "was"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "developed"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "2004"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "by"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "John"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "Gruber,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "who"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "wrote"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "the"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "first"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "Markdown-to-HTML"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "converter"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "perl,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "and"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "it"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "soon"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "became"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "widely"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "used"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "websites."},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "By"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "2014"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "there"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "were"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "dozens"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "of"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "implementations"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "many"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "languages."},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "Some"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "of"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "them"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "extended"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "basic"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "Markdown"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "syntax"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "with"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "conventions"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "for"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "footnotes,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "definition"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "lists,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "tables,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "and"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "other"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "constructs,"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "and"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "some"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "allowed"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "output"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "not"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "just"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "HTML"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "but"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "in"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "LaTeX"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "and"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "many"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "other"},
      {"t": "Space", "c": []},
      {"t": "Str", "c": "formats."}]}]]

我如何改变/重新格式化这一点,以便当"t""c"是字典键时,我得到一个更易读的字典,其中字典键t的值是关键字我的新词典,'c'的值是我的新词典的值。

成功的结果看起来像这样:

{
    "unMeta": {
      "date": {
        "MetaInlines": [
          {"Str": "2015-08-23"}]},
      "version": {
        "MetaString": "0.22"},
      "author": {
        "MetaInlines": [
          {"Str": "John"},
          {"Space": []},
          {"Str": "MacFarlane"}]},
      "title": {
        "MetaInlines": [
          {"Str": "CommonMark"},
          {"Space": []},
          {"Str": "Spec"}]},
      "license": {
        "MetaInlines": [
          {"Link": [
            [
              {"Str": "CC-BY-SA"},
              {"Space": []},
              {"Str": "4.0"}
            ],
            ["http://creativecommons.org/licenses/by-sa/4.0/", ""]]
          }
        ]
      }
    }
  },

我目前的策略是这样的。在一个while循环中我迭代直到找到"t""c"作为字典的键,然后我在包含键的字典上调用一个函数,返回一个新字典,将found设置为True并覆盖原始字典值,然后让while循环运行,直到找不到更多实例。还有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

你的循环如何检查主列表中的所有词典,这些词典中的所有词典,以及每个内部词典中的词典列表等等?这种类型的问题通常通过递归来解决。此函数将遍历原始列表中的值。遇到{'t':x, 'c':y}词典时,它会将其更改为{x: y}。当遇到任何其他类型的字典或列表时,该函数会在项目上调用它自己。

def mutate(iterable):
    if isinstance(iterable, list):
        indexed_list = enumerate(iterable)
    elif isinstance(iterable, dict):
        indexed_list = iterable.items()
    for k, item in indexed_list:
        if isinstance(item, dict) and sorted(item.keys()) == ['c', 't']:
            iterable[k] = {item['t']: item['c']}
        if isinstance(item, dict) or isinstance(item, list):
            mutate(item)