【问题标题】:Pythonic way to extract keys and multiple values from a list of dicts从字典列表中提取键和多个值的 Pythonic 方法
【发布时间】:2021-03-09 09:46:48
【问题描述】:

我有一些有效的代码,从文本文件中读取数据作为字典列表,代码从 for 循环中的每个字典中获取键和值。虽然它有效,但我确信有比我下面的更好的方法:

代码

data_list = [{'Clk': '190', '50%': '5.3149999999999995', '100%': '4.715'}, 
{'Clk': '195', '50%': '5.295', '100%': '4.765'}, 
{'Clk': '200', '50%': '5.395', '100%': '4.9'}, 
{'Clk': '205', '50%': '5.55', '100%': '4.970000000000001'},
 {'Clk': '210', '50%': '5.68', '100%': '5.005'}, 
 {'Clk': '215', '50%': '5.725', '100%': '5.08'}, 
 {'Clk': '220', '50%': '5.85', '100%': '5.215'}, 
 {'Clk': '225', '50%': '6.03', '100%': '5.35'}, 
 {'Clk': '230', '50%': '6.140000000000001', '100%': '5.395'},
  {'Clk': '235', '50%': '6.074999999999999', '100%': '5.37'}, 
  {'Clk': '240', '50%': '6.02', '100%': '5.345'}, 
  {'Clk': '245', '50%': '6.025', '100%': '5.49'}, 
{'Clk': '290', '50%': '5.67', '100%': '5.37'}]

#print(data_list)
#print('\n'*3)
Clk = []
av_50 = []
av_100 = []
for dicty in data_list:
    for k,v in dicty.items():
        #print("  ", v)
        if k == "Clk":
            Clk.append(dicty["Clk"])
        if k == "50%":
            av_50.append(dicty["50%"])
        if k == "100%":
            av_100.append(dicty["100%"])
print('\n'*3)
print(Clk)
print('\n')
print(av_50)
print('\n')
print(av_100)

输出

['190', '195', '200', '205', '210', '215', '220', '225', '230', '235', '240', '245', '290']


['5.3149999999999995', '5.295', '5.395', '5.55', '5.68', '5.725', '5.85', '6.03', '6.140000000000001', '6.074999999999999', '6.02', '6.025', '5.67']


['4.715', '4.765', '4.9', '4.970000000000001', '5.005', '5.08', '5.215', '5.35', '5.395', '5.37', '5.345', '5.49', '5.37']

【问题讨论】:

  • 您可以使用列表推导,但效率不高,因为与您当前的解决方案相比,它会遍历列表三次。

标签: python list dictionary


【解决方案1】:

您可以使用 zip 浏览字典并将 3 个字段映射到单独的列表中:

data_list = [{'Clk': '190', '50%': '5.3149999999999995', '100%': '4.715'}, 
    {'Clk': '195', '50%': '5.295', '100%': '4.765'}, 
    {'Clk': '200', '50%': '5.395', '100%': '4.9'}, 
    {'Clk': '205', '50%': '5.55', '100%': '4.970000000000001'},
    {'Clk': '210', '50%': '5.68', '100%': '5.005'}, 
    {'Clk': '215', '50%': '5.725', '100%': '5.08'}, 
    {'Clk': '220', '50%': '5.85', '100%': '5.215'}, 
    {'Clk': '225', '50%': '6.03', '100%': '5.35'}, 
    {'Clk': '230', '50%': '6.140000000000001', '100%': '5.395'},
    {'Clk': '235', '50%': '6.074999999999999', '100%': '5.37'}, 
    {'Clk': '240', '50%': '6.02', '100%': '5.345'}, 
    {'Clk': '245', '50%': '6.025', '100%': '5.49'}, 
    {'Clk': '290', '50%': '5.67', '100%': '5.37'}
]

Clk, av_50, av_100 = map(list,zip(*((d["Clk"],d["50%"],d["100%"]) for d in data_list)))

print(Clk)
print(av_50)
print(av_100)

['190', '195', '200', '205', '210', '215', '220', '225', '230', '235', '240', '245', '290']
['5.3149999999999995', '5.295', '5.395', '5.55', '5.68', '5.725', '5.85', '6.03', '6.140000000000001', '6.074999999999999', '6.02', '6.025', '5.67']
['4.715', '4.765', '4.9', '4.970000000000001', '5.005', '5.08', '5.215', '5.35', '5.395', '5.37', '5.345', '5.49', '5.37']

对于更通用的公式,您可以将键与列表理解分开:

keys = ("Clk","50%","100%")
Clk,av_50,av_100 = map(list,zip(*(map(d.get,keys) for d in data_list)))

这将允许创建一个通用的密钥提取函数:

def listKeys(D,*keys):
    return map(list,zip(*(map(d.get,keys) for d in D)))

Clk,av_50,av_100 = listKeys(data_list,"Clk","50%","100%")

【讨论】:

  • 漂亮的 oneliners 总是让我高兴,漂亮的一个,没有看到如何结合这三个 :) 你能指出我在这个例子中找到 * 功能的方向吗?
  • * 运算符将迭代器解包为 zip() 函数的各个参数。有关拆包的更多详细信息,请参见此处:geeksforgeeks.org/packing-and-unpacking-arguments-in-python
  • 啊,这很有意义!非常感谢,我将来会使用它 :) 你是让我的 oneliners 更有效率的英雄 :)
【解决方案2】:
data_list = [
    {'Clk': '190', '50%': '5.3149999999999995', '100%': '4.715'}, 
    {'Clk': '195', '50%': '5.295', '100%': '4.765'}, 
    {'Clk': '200', '50%': '5.395', '100%': '4.9'}, 
    {'Clk': '205', '50%': '5.55', '100%': '4.970000000000001'},
    {'Clk': '210', '50%': '5.68', '100%': '5.005'}, 
    {'Clk': '215', '50%': '5.725', '100%': '5.08'}, 
    {'Clk': '220', '50%': '5.85', '100%': '5.215'}, 
    {'Clk': '225', '50%': '6.03', '100%': '5.35'}, 
    {'Clk': '230', '50%': '6.140000000000001', '100%': '5.395'},
    {'Clk': '235', '50%': '6.074999999999999', '100%': '5.37'}, 
    {'Clk': '240', '50%': '6.02', '100%': '5.345'}, 
    {'Clk': '245', '50%': '6.025', '100%': '5.49'}, 
    {'Clk': '290', '50%': '5.67', '100%': '5.37'}
]

Clk = [data_point['Clk'] for data_point in data_list] # shortcode for creating list with iterator

av_50 = [data_point['50%'] for data_point in data_list]

av_100 = [data_point['100%'] for data_point in data_list]

【讨论】:

    【解决方案3】:

    我会推荐使用pandas.DataFrame 非常方便的方式

    import pandas as pd
    
    data_list = [{'Clk': '190', '50%': '5.3149999999999995', '100%': '4.715'}, 
    {'Clk': '195', '50%': '5.295', '100%': '4.765'}, 
    {'Clk': '200', '50%': '5.395', '100%': '4.9'}, 
    {'Clk': '205', '50%': '5.55', '100%': '4.970000000000001'},
     {'Clk': '210', '50%': '5.68', '100%': '5.005'}, 
     {'Clk': '215', '50%': '5.725', '100%': '5.08'}, 
     {'Clk': '220', '50%': '5.85', '100%': '5.215'}, 
     {'Clk': '225', '50%': '6.03', '100%': '5.35'}, 
     {'Clk': '230', '50%': '6.140000000000001', '100%': '5.395'},
      {'Clk': '235', '50%': '6.074999999999999', '100%': '5.37'}, 
      {'Clk': '240', '50%': '6.02', '100%': '5.345'}, 
      {'Clk': '245', '50%': '6.025', '100%': '5.49'}, 
    {'Clk': '290', '50%': '5.67', '100%': '5.37'}]
    
    my_data=pd.DataFrame(data_list)
    
    
    clk = my_data['Clk'].tolist()
    clk
    

    问候

    【讨论】:

      【解决方案4】:

      Felix 的回答有效,但如果您想继续检查密钥是否存在,您可以这样做:

      data_list = [
          {'Clk': '190', '50%': '5.3149999999999995', '100%': '4.715'}, 
          {'Clk': '195', '50%': '5.295', '100%': '4.765'}, 
          {'Clk': '200', '50%': '5.395', '100%': '4.9'}, 
          {'Clk': '205', '50%': '5.55', '100%': '4.970000000000001'},
          {'Clk': '210', '50%': '5.68', '100%': '5.005'}, 
          {'Clk': '215', '50%': '5.725', '100%': '5.08'}, 
          {'Clk': '220', '50%': '5.85', '100%': '5.215'}, 
          {'Clk': '225', '50%': '6.03', '100%': '5.35'}, 
          {'Clk': '230', '50%': '6.140000000000001', '100%': '5.395'},
          {'Clk': '235', '50%': '6.074999999999999', '100%': '5.37'}, 
          {'Clk': '240', '50%': '6.02', '100%': '5.345'}, 
          {'Clk': '245', '50%': '6.025', '100%': '5.49'}, 
          {'Clk': '290', '50%': '5.67', '100%': '5.37'}
      ]
      
      Clk = [dicty["Clk"] for dicty in data_list if "Clk" in dicty.keys()]
      av_50 = [dicty["50%"] for dicty in data_list if "50%" in dicty.keys()]
      av_100 = [dicty["100%"] for dicty in data_list if "100%" in dicty.keys()]
      

      【讨论】:

        【解决方案5】:

        没有任何额外库的基本(和最佳)解决方案:

        clk = []
        av_50 = []
        av_100 = []
        
        for item in data_list:
            clk.append(item['Clk'])
            av_50.append(item['50%'])
            av_100.append(item['100%'])
        
        print(clk)
        print(av_50)
        print(av_100)
        

        更优雅的列表推导解决方案,虽然效率较低,因为它需要对 data_list 进行三次迭代,而不是之前的方法只需要一次迭代

        clk = []
        av_50 = []
        av_100 = []
        
        clk = [item['Clk'] for item in data_list]
        av_50 = [item['50%'] for item in data_list]
        av_100 = [item['100%'] for item in data_list]
        
        print(clk)
        print(av_50)
        print(av_100)
        

        【讨论】:

          【解决方案6】:

          使用动态数据收集可能会很方便,以防您的 dict 结构可能随时间发生变化。这适用于您的data_list

          def explode(data_list):
              keys = list(data_list[0].keys())
              values = [[d[k] for k in keys] for d in data_list]
              return keys, values
          
          keys, values = explode(data_list)
          

          然后print(keys) 输出

          ['Clk', '50%', '100%'`]
          

          print(values):

          [['190', '5.3149999999999995', '4.715'], ['195', '5.295', '4.765'], ['200', '5.395', '4.9'], ['205', '5.55', '4.970000000000001'], ['210', '5.68', '5.005'], ['215', '5.725', '5.08'], ['220', '5.85', '5.215'], ['225', '6.03', '5.35'], ['230', '6.140000000000001', '5.395'], ['235', '6.074999999999999', '5.37'], ['240', '6.02', '5.345'], ['245', '6.025', '5.49'], ['290', '5.67', '5.37']]
          

          【讨论】:

            猜你喜欢
            • 2021-09-17
            • 1970-01-01
            • 2014-08-07
            • 2023-02-23
            • 1970-01-01
            • 2021-08-01
            • 2016-02-11
            • 2015-03-20
            • 2019-05-03
            相关资源
            最近更新 更多