【问题标题】:Getting a list of values from a list of dicts从字典列表中获取值列表
【发布时间】:2011-11-08 10:42:46
【问题描述】:

我有一个这样的字典列表:

[{'value': 'apple', 'blah': 2}, 
 {'value': 'banana', 'blah': 3} , 
 {'value': 'cars', 'blah': 4}]

我要['apple', 'banana', 'cars']

最好的方法是什么?

【问题讨论】:

    标签: python list dictionary


    【解决方案1】:

    假设每个 dict 都有一个 value 键,您可以编写(假设您的列表名为 l

    [d['value'] for d in l]
    

    如果value 可能丢失,您可以使用

    [d['value'] for d in l if 'value' in d]
    

    【讨论】:

    • 要处理键的缺失值,也可以使用 d.get("key_to_lookup", "alternate_value")。然后,它看起来像: [d.get('value', 'alt') for d in l] 。如果 value 不作为 key 存在,它将简单地返回 'alt'。
    • 这种“魔法”被称为列表理解docs.python.org/3/tutorial/…
    • 救命稻草!长期以来,我一直在尝试/搜索 sqlalchemy 对象。现在它像[d.value for d in l]一样工作,谢谢:)
    【解决方案2】:
    [x['value'] for x in list_of_dicts]
    

    【讨论】:

    • 或 [d.getkey('value') for d in dict_list]
    • @rpInt 嗯,没有getkey..你的意思是d.get('value')吗?这与@isbadawi 的第二个列表理解相同,而不是 Michal 的。
    • 是的,对不起,我的意思是得到。我的意思是,如果缺少密钥,它不会引发异常。但是@isbadawi 的解决方案更好,因为当密钥丢失时 get() 将提供 None (或我们指定的默认值)。
    【解决方案3】:

    这是另一种使用 map() 和 lambda 函数的方法:

    >>> map(lambda d: d['value'], l)
    

    其中 l 是列表。 我认为这种方式“最性感”,但我会使用列表理解来做到这一点。

    更新: 如果可能缺少“价值”作为关键用途:

    >>> map(lambda d: d.get('value', 'default value'), l)
    

    更新:我也不是 lambdas 的忠实粉丝,我更喜欢命名...这就是我将这样做的方式:

    >>> import operator
    >>> get_value = operator.itemgetter('value')
    >>> map(get_value, l)
    

    我什至会更进一步,创建一个明确说明我想要实现的目标的函数:

    >>> import operator, functools
    >>> get_value = operator.itemgetter('value')
    >>> get_values = functools.partial(map, get_value)
    >>> get_values(l)
    ... [<list of values>]
    

    在 Python 3 中,由于 map 返回一个迭代器,所以使用 list 返回一个列表,例如list(map(operator.itemgetter('value'), l)).

    【讨论】:

    • 列表理解在这里更有意义。
    • 如果您要使用第一个map,请使用operator.itemgetter('value'),而不是lambda
    【解决方案4】:

    对于这样一个非常简单的情况,理解,如Ismail Badawi's answer 绝对是要走的路。

    但是当事情变得更加复杂,并且您需要开始编写包含复杂表达式的多子句或嵌套推导式时,就值得研究其他替代方案。有几种不同的(准)标准方法可以在嵌套的 dict-and-list 结构(例如 JSONPath、DPath 和 KVC)上指定 XPath 样式的搜索。 PyPI 上有很好的库供他们使用。

    这是一个名为 dpath 的库的示例,展示了它如何简化一些更复杂的事情:

    >>> dd = {
    ...     'fruits': [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3}],
    ...     'vehicles': [{'value': 'cars', 'blah':4}]}
    
    >>> {key: [{'value': d['value']} for d in value] for key, value in dd.items()}
    {'fruits': [{'value': 'apple'}, {'value': 'banana'}],
     'vehicles': [{'value': 'cars'}]}
    
    >>> dpath.util.search(dd, '*/*/value')
    {'fruits': [{'value': 'apple'}, {'value': 'banana'}],
     'vehicles': [{'value': 'cars'}]}
    

    或者,使用jsonpath-ng

    >>> [d['value'] for key, value in dd.items() for d in value]
    ['apple', 'banana', 'cars']
    >>> [m.value for m in jsonpath_ng.parse('*.[*].value').find(dd)]
    ['apple', 'banana', 'cars']
    

    这个乍一看可能不那么简单,因为find返回匹配对象,除了匹配的值之外,还包括各种东西,比如直接指向每个项目的路径。但是对于更复杂的表达式,能够为每个* 指定一个类似'*.[*].value' 的路径而不是一个理解子句会产生很大的不同。此外,JSONPath 是一种与语言无关的规范,甚至还有 online testers 可以非常方便地进行调试。

    【讨论】:

      【解决方案5】:

      一个非常简单的方法是:

      list1=['']
      j=0
      for i in com_list:
          if j==0:
              list1[0]=(i['value'])
          else:
              list1.append(i['value'])
          j+=1
      

      输出:

      ['苹果','香蕉','汽车']

      【讨论】:

        【解决方案6】:

        我认为像下面这样简单可以满足您的需求。

        In[5]: ll = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}]
        In[6]: ld = [d.get('value', None) for d in ll]
        In[7]: ld
        Out[7]: ['apple', 'banana', 'cars']
        

        您也可以使用 maplambda 的组合来完成此操作,但列表解析看起来更优雅和 Python。

        对于较小的输入,列表理解是可行的方法,但如果输入真的很大,那么我猜生成器是理想的方式。

        In[11]: gd = (d.get('value', None) for d in ll)
        In[12]: gd
        Out[12]: <generator object <genexpr> at 0x7f5774568b10>
        In[13]: '-'.join(gd)
        Out[13]: 'apple-banana-cars'
        

        这里是更大输入的所有可能解决方案的比较

         In[2]: l = [{'value': 'apple', 'blah': 2}, {'value': 'banana', 'blah': 3} , {'value': 'cars', 'blah':4}] * 9000000
        In[3]: def gen_version():
          ...:     for i in l:
          ...:         yield i.get('value', None)
          ...: 
        In[4]: def list_comp_verison():
          ...:     return [i.get('value', None) for i in l]
          ...: 
        In[5]: def list_verison():
          ...:     ll = []
          ...:     for i in l:
          ...:         ll.append(i.get('value', None))
          ...:     return ll
        In[10]: def map_lambda_version():
           ...:      m = map(lambda i:i.get('value', None), l)
           ...:      return m
           ...: 
        In[11]: %timeit gen_version()
        172 ns ± 0.393 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
        In[12]: %timeit map_lambda_version()
        203 ns ± 2.31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
        In[13]: %timeit list_comp_verison()
        1.61 s ± 20.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
        In[14]: %timeit list_verison()
        2.29 s ± 4.58 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
        

        如您所见,生成器与其他解决方案相比是更好的解决方案,地图也比生成器慢,原因我将留给 OP 来解决。

        【讨论】:

          【解决方案7】:

          按照示例进行操作 --

          songs = [
          {"title": "happy birthday", "playcount": 4},
          {"title": "AC/DC", "playcount": 2},
          {"title": "Billie Jean", "playcount": 6},
          {"title": "Human Touch", "playcount": 3}
          ]
          
          print("===========================")
          print(f'Songs --> {songs} \n')
          title = list(map(lambda x : x['title'], songs))
          print(f'Print Title --> {title}')
          
          playcount = list(map(lambda x : x['playcount'], songs))
          print(f'Print Playcount --> {playcount}')
          print (f'Print Sorted playcount --> {sorted(playcount)}')
          
          # Aliter -
          print(sorted(list(map(lambda x: x['playcount'],songs))))
          

          【讨论】:

            【解决方案8】:

            从python中的字典列表中获取键值?

            1. 从 python 中的字典列表中获取键值?

            例如:

            data = 
            [{'obj1':[{'cpu_percentage':'15%','ram':3,'memory_percentage':'66%'}]},
            {'obj2': [{'cpu_percentage':'0','ram':4,'memory_percentage':'35%'}]}]
            

            对于数据中的 d:

              for key,value in d.items(): 
            
                  z ={key: {'cpu_percentage': d['cpu_percentage'],'memory_percentage': d['memory_percentage']} for d in value} 
                  print(z)
            

            输出:

            {'obj1': {'cpu_percentage': '15%', 'memory_percentage': '66%'}}
            {'obj2': {'cpu_percentage': '0', 'memory_percentage': '35%'}}
            

            【讨论】:

              【解决方案9】:

              请试试这个。

              d =[{'value': 'apple', 'blah': 2},  {'value': 'banana', 'blah': 3} , {'value': 
              'cars', 'blah': 4}] 
              b=d[0]['value']
              c=d[1]['value']
              d=d[2]['value']
              new_list=[b,c,d]
              print(new_list)
              

              输出:

              ['apple', 'banana', 'cars']
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-08-22
                相关资源
                最近更新 更多