【问题标题】:how to convert list of dict to dict如何将字典列表转换为字典
【发布时间】:2011-07-11 07:31:57
【问题描述】:

如何将字典列表转换为字典。下面是dict列表

data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
        {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
        {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]

data = {{'name': 'John Doe', 'age': 37, 'sex': 'M'},
        {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
        {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}}

【问题讨论】:

  • 尝试将您的第二行放入 Python 脚本并运行它。它甚至会正常运行吗?我不这么认为......
  • 您的问题在发布时并没有真正的意义。您希望结果 dict 的键和关联值是什么?你写的第二件事不是一个有效的 Python 对象。
  • 您想要的输出不是字典,而是集合!编辑问题也许是为了避免混淆

标签: python list dictionary


【解决方案1】:

使用名称作为新键的可能解决方案:

new_dict = {}
for item in data:
   name = item['name']
   new_dict[name] = item

在 python 3.x 中,您还可以以更好的方式将 dict 推导用于相同的方法:

new_dict = {item['name']:item for item in data}

正如 Paul McGuire 在评论中所建议的那样,如果您不想在内部字典中使用该名称,您可以这样做:

new_dict = {}
for item in data:
   name = item.pop('name')
   new_dict[name] = item

【讨论】:

  • 这将留下一个额外的名称字段,这可能是也可能不是用户想要的。 (即,新字典看起来像{'Lisa Simpson': {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'} ...}
  • 在指定name后加上"item.pop('name')",就不会得到额外的name字段了。
  • @Platinum — 当使用字典作为查找表时,这实际上很常见。然后另一个数据结构可以直接引用字典值而不会丢失键(而不是存储键并在每次访问时在表中查找它)。
  • @Platinum Azure:你是对的,但 OP 问题在这方面没有提供任何线索。这只是一个可能的解决方案。当我想使用主题信息中的值从主题获取完整信息时,我在某些应用程序中使用了类似的字典(使用冗余字段)。显然,也可以使用其他主键,或者按照建议,从原始字典中消除冗余键。
  • 如果data 是动态的并且没有固定的name 键怎么办?有没有办法解决这个问题?仅在我的情况下,我遇到了类似的问题,data 由 MongoDB 查询组成,因此它不是静态的。
【解决方案2】:

python3.3及以上可以使用ChainMap

ChainMap 将多个 dicts 或其他映射组合在一起以创建 一个单一的、可更新的视图。如果未指定地图,则为单个空 提供字典以便一个新的链总是至少有一个 映射。

from collections import ChainMap

data = dict(ChainMap(*data))

【讨论】:

  • 这是要走的路。
  • 优雅。不错的答案
  • 这能保证更快吗?以前的答案在整个列表上迭代,所以是 O(n),ChainMap 是不是小于这个?
  • 它只返回行的第一个条目作为字典。
【解决方案3】:

如果字典不共享密钥,那么你可以使用:

dict((key,d[key]) for d in data for key in d)

在您的情况下,生成带有列表作为值的 dict 可能更好?

newdict={}
for k,v in [(key,d[key]) for d in data for key in d]:
  if k not in newdict: newdict[k]=[v]
  else: newdict[k].append(v)

这会产生:

>>> newdict
`{'age': [37, 17, 57], 'name': ['John Doe', 'Lisa Simpson', 'Bill Clinton'], 'sex': ['M', 'F', 'M']}`

【讨论】:

    【解决方案4】:

    试试这个方法:

    dict((key, val) for k in data for key, val in k.items())
    

    【讨论】:

      【解决方案5】:

      我们不要过于复杂:

      simple_dictionary = dict(data[0])
      

      【讨论】:

      • 这不是解决方案,但它对我的问题有所帮助,所以我赞成这个
      【解决方案6】:

      也许您希望名称成为关键?您没有真正指定,因为您的第二个示例无效且没有真正意义。

      请注意,我的示例从值中删除了键“名称”,这可能是可取的(也可能不是)。

      data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
              {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
              {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
      newdata = {}
      for entry in data:
          name = entry.pop('name') #remove and return the name field to use as a key
          newdata[name] = entry
      print newdata
      ##{'Bill Clinton': {'age': 57, 'sex': 'M'},
      ## 'John Doe': {'age': 37, 'sex': 'M'},
      ## 'Lisa Simpson': {'age': 17, 'sex': 'F'}}
      print newdata['John Doe']['age']
      ## 37
      

      【讨论】:

      • 这取决于你如何解读《辛普森一家》。毕竟,如果她在 1989 年演出开始时是 8 岁,那么今天她应该是 29 或 30 岁……:-)
      【解决方案7】:

      以防万一您想要一个功能替代品(也假设需要名称作为新键),您可以这样做

      from toolz.curried import *
      
      data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
              {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
              {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
      
      newdata = pipe(data, 
                     map(lambda x: {x['name']: dissoc(x, 'name')}),
                     lambda x: merge(*x)
      )
      
      print(newdata)
      

      【讨论】:

        【解决方案8】:
        import pandas as pd
        data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
                {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
                {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
        
        print(pd.DataFrame(data).to_dict())
        

        【讨论】:

          猜你喜欢
          • 2018-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-09
          • 2017-04-23
          • 2021-10-13
          相关资源
          最近更新 更多