【问题标题】:Python create list from list of dictionaries for each dictionary that has a specific key [duplicate]Python从具有特定键的每个字典的字典列表中创建列表[重复]
【发布时间】:2016-10-26 23:08:10
【问题描述】:

我有一个不一定具有相同键的字典列表。我正在尝试为每个具有特定键的字典中包含的值创建一个新列表。

例如

dict1 = {'key1': 1, 'key2': 2, 'key4': 4}
dict2 = {'key2': 2, 'key3': 3}
dict3 = {'key1': 1, 'key2': 2, 'key3': 3}

dict_list = [dict1, dict2, dict3]

现在我正在尝试从 dict_list 创建一个列表,如下所示:

key2vals = [dict['key2'] for dict in dict_list]
print(key2vals)
   [2, 2, 2]

效果很好,因为列表中的每个字典都包含“key2”。但是,当我尝试一个没有出现在每个字典中的键时,我会出错。例如。 'key1':

>>> key1vals = [dict['key1'] for dict in dict_list]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
KeyError: 'key1'

有没有一种简单直接的方法可以让我执行以下操作,但这是行不通的?

# This does not work
key1vals = [dict['key1'] if 'key1' in dict for dict in dict_list]

实现这一点的最 Pythonic 方式是什么?

回答: for 和 if 语句的顺序应该颠倒:

key1vals = [dict['key1'] for dict in dict_list if 'key1' in dict ]

此外,根据 AbrahamB 和 DJV 的建议,我能够在没有搜索键的情况下为这些字典添加默认值:

[dict.get('key1', 0) for dict in dict_list] 

【问题讨论】:

    标签: python dictionary key


    【解决方案1】:
    dict1 = {'key1': 1, 'key2': 2, 'key4': 4}
    dict2 = {'key2': 2, 'key3': 3}
    dict3 = {'key1': 1, 'key2': 2, 'key3': 3}
    
    dict_list = [dict1, dict2, dict3]
    
    keys = ['key1', 'key2', 'key3', 'key4', 'key5']
    for key in keys:
        values = [d[key] for d in dict_list if key in d]
        print(values)
    
    [1, 1]
    [2, 2, 2]
    [3, 3]
    [4]
    []
    

    但相同的项目查找在这里进行了两次:key in dd[key]。你可以避免它:

        values = list(filter(None, (d.get(key) for d in dict_list)))
    

        values = [i for i in (d.get(key) for d in dict_list) if i is not None]
    

    添加: 正如您在 cmets 中提到的,如果 key 不在字典中,您实际上需要0。只需使用带有默认值的get 方法:

        values = [d.get(key, 0) for d in dict_list]
    
    [1, 0, 1]
    [2, 2, 2]
    [0, 3, 3]
    [4, 0, 0]
    [0, 0, 0]
    

    【讨论】:

      【解决方案2】:

      当然。 dict 有一个“get”方法,你可以使用它。

      例如

      a = {}
      a.get('this-does-not-exist')
      

      这将返回 None 类型。

      现在你可以变得更花哨了,比如如果没有找到就返回一个默认值:

      a = {}
      a.get('this-does-not-exist', [])
      

      这将返回一个空列表 []。

      【讨论】:

      • 原样题中的a.get('key', 'defaultValue') 格式能用吗?我不太了解如何在更大的范围内使用它。
      • DJV 刚刚在另一条评论中提供了答案:[d.get('key1', 0) for d in dict_list]
      【解决方案3】:

      你已经很接近了:

      key1vals = [d['key1'] for d in dict_list if 'key1' in d]
      

      获取所有键的值:

      all_keys = {key for d in dict_list for key in d}
      
      result_dict = {}
      for key in all_keys:
          result_dict[key] = [d[key] for d in dict_list if key in d]
      
      print(result_dict)
      

      哪些打印:

      {'key1': [1, 1], 'key4': [4], 'key3': [3, 3], 'key2': [2, 2, 2]}
      

      【讨论】:

        【解决方案4】:

        感谢您的建议!我找到了另一种解决方案,它只是颠倒了我之前尝试中的“for”和“if”语句:

        >>> key1vals = [dict['key1'] for dict in dict_list if 'key1' in dict]
        >>> key1vals
        [1, 1]
        >>> 
        

        过滤器或“get”方法会比这更受欢迎吗?

        【讨论】:

        • 我建议使用 get ,因为它更干净。您已经在 dict['key1'] 中调用了键,所以这会更短,就像 dict.get('key1')
        • 不管怎样。是的,它更短,但我认为if 'key1' in d 语言可能更 Pythonic 并且更易于阅读。这种方法从字面上检查字典是否甚至有一个键'key1'。无论哪种方式,您都不会出错。
        • 我可以添加一个“else”语句,例如>>>key1vals = [dict['key1'] for dict in dict_list if 'key1' in dict else 0]。然后我希望 key1vals 包含 [1, 0, 1]。
        • [d.get('key1', 0) for d in dict_list]
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-22
        • 2021-09-04
        • 2020-06-30
        • 2022-11-12
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        相关资源
        最近更新 更多