【问题标题】:List of lists of strings to a list of dictionaries字符串列表列表到字典列表
【发布时间】:2021-03-17 05:13:18
【问题描述】:

我有一长串格式如下的列表:

[
  [
    'iyr:1928',
    'cid:150',
    'pid:476113241',
    'eyr:2039',
    'hcl:a5ac0f',
    'ecl:#25f8d2',
    'byr:2027',
    'hgt:190'
  ],
  [
    'hgt:168cm',
    'eyr:2026',
    'ecl:hzl',
    'hcl:#fffffd',
    'cid:169',
    'pid:920076943',
    'byr:1929',
    'iyr:2013'
  ],
  ...
]

我想把它转换成这样的字典列表:

[
    {
        "iyr": "1928",
        "cid": "150",
        "pid": "476113241",
        "eyr": "2039",
        "hcl": "a5ac0f",
        "ecl": "#25f8d2",
        "byr": "2027",
        "hgt": "190"
    },
    {
        "hgt": "168cm",
        "eyr": "2026",
        "ecl": "hzl",
        "hcl": "#fffffd",
        "cid": "169",
        "pid": "920076943",
        "byr": "1929",
        "iyr": "2013"
    },
    ...
]

我知道我必须 split(':') 每个列表中的每个条目,但我不知道如何将该块转换为字典。

【问题讨论】:

  • 最好包括您到目前为止尝试过的内容以及您的意外结果
  • 您应该首先弄清楚如何将单个列表转换为字典,然后将解决方案扩展到多个列表。如需单个列表,请参阅:Convert list of strings to dictionary

标签: python list dictionary


【解决方案1】:

这个答案也考虑了您的字符串中的多个:,并且不依赖于索引列表:

lol = [
  [
    'iyr:1928',
    'cid:150',
    'pid:476113241',
    'eyr:2039',
    'hcl:a5ac0f',
    'ecl:#25f8d2',
    'byr:2027',
    'hgt:190'
  ],
  [
    'hgt:168cm',
    'eyr:2026',
    'ecl:hzl',
    'hcl:#fffffd',
    'cid:169',
    'pid:920076943',
    'byr:1929',
    'iyr:2013'
  ]
]

res = [dict([tuple(i.split(':', maxsplit=1)) for i in l]) for l in lol]
print(res)
'''
[
  {
    "iyr":"1928",
    "cid":"150",
    "pid":"476113241",
    "eyr":"2039",
    "hcl":"a5ac0f",
    "ecl":"#25f8d2",
    "byr":"2027",
    "hgt":"190"
  },
  {
    "hgt":"168cm",
    "eyr":"2026",
    "ecl":"hzl",
    "hcl":"#fffffd",
    "cid":"169",
    "pid":"920076943",
    "byr":"1929",
    "iyr":"2013"
  }
]
'''

cProfiling 产量:

cProfile.run('res = [dict([tuple(i.split(":", maxsplit=1)) for i in l]) for l in lol]')

         20 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <string>:1(<listcomp>)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
       16    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}

与公认的解决方案相比:

cProfile.run('res = [{entry.split(":")[0] : entry.split(":")[1] for entry in entries} for entries in myarray]')

         38 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        2    0.000    0.000    0.000    0.000 <string>:1(<dictcomp>)
        1    0.000    0.000    0.000    0.000 <string>:1(<listcomp>)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
       32    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}

因此,我提出的解决方案对于 OP 提到的 large 列表列表确实可以更好地扩展。

【讨论】:

    【解决方案2】:

    您可以检查列表中的每个项目,然后对于每个项目(这是一个列表),检查其项目,将它们按: 拆分(按照您的建议!)并使用第一个项目作为键和第二个作为值。

    使用列表和字典推导,这甚至可以是一个单行器:

    result = [{s.split(':')[0]:s.split(':')[1] for s in l} for l in lst]
    

    【讨论】:

    • 这会产生一个列表列表,其中每个列表都包含一个字典,每个列表都有自己的键:值
    • @Buster 哎呀,确实!很好的收获,谢谢。已编辑和修复。
    【解决方案3】:

    除了其他更简洁的答案外,这里还有一个更详细的版本,可以做同样的事情

    def list_to_dict(elements):
      elem_dict = {}
      for elem in elements:
        k, v = elem.split(":")
        elem_dict[k] = v
      return elem_dict
    
    
    list_of_lists = [
      [
        'iyr:1928',
        'cid:150',
        'pid:476113241',
        'eyr:2039',
        'hcl:a5ac0f',
        'ecl:#25f8d2',
        'byr:2027',
        'hgt:190'
      ],
      [
        'hgt:168cm',
        'eyr:2026',
        'ecl:hzl',
        'hcl:#fffffd',
        'cid:169',
        'pid:920076943',
        'byr:1929',
        'iyr:2013'
      ],
    ]
    
    list_of_dicts = map(list_to_dict, list_of_lists)
    
    print(list_of_lists)
    print(list_of_dicts)
    

    【讨论】:

      【解决方案4】:

      我喜欢简短易读的版本,所以我可能会这样做:

      make_dict = lambda list_item : {x.split(':')[0]:x.split(':')[1] for x in list_item}
      l1 = [make_dict(item) for item in org_list]
      

      【讨论】:

        【解决方案5】:
          [{entry.split(':')[0] : entry.split(':')[1] for entry in entries} for entries in myarray]
        

        【讨论】:

          猜你喜欢
          • 2012-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多