【问题标题】:Filter a list of dictionaries based on another list of strings根据另一个字符串列表过滤字典列表
【发布时间】:2021-03-25 21:10:51
【问题描述】:

我有一个字典列表,如下所示

data = [{'Person1':['a', 'b', 'c']}, {'Person2':['1', '2', '3']}, {'Person3':['x', 'y', 'z']}]

它包含近 7000000 个字典。然后我有一个字符串列表,例如

people = ['person1', 'person3']

长度为 450000。此列表中的所有字符串都作为字典列表中的键存在。

根据这个字符串列表过滤字典列表的最快/最有效的方法是什么,以便返回一个只包含与列表中的字符串对应的键的新字典,例如

d = {'Person1':['a', 'b', 'c']}, 'Person3':['x', 'y', 'z']}

这是我的代码,但它需要很长时间才能运行,我想知道解决这个问题的最佳方法是什么。

d = {}

for p in people:
    for i in data:
        for k in i:
            if p == k.lower():
               d[p] = i[k]

【问题讨论】:

    标签: python-3.x list dictionary


    【解决方案1】:

    很少的基准测试 -

    嵌套的 For 循环

    %%timeit
    
    out = []
    for i in data:
        for j in people:
            if list(i.keys())[0]==j:
                out.append(i)
                
    #1.78 µs ± 55.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)            
    

    列表理解与in

    %%timeit
    
    out = [i for i in data if list(i.keys())[0] in people]
    
    #1.02 µs ± 36.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    列表理解与set.intersection

    %%timeit
    
    out = [i for i in data if set(i).intersection(people)]
    
    #1.04 µs ± 27.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    【讨论】:

      【解决方案2】:

      使用 dict-comprehension 的第一个建议:

      from collections import ChainMap
      
      data = [
          {'Person1':['a', 'b', 'c']}, 
          {'Person2':['1', '2', '3']}, 
          {'Person3':['x', 'y', 'z']}
      ]
      people = ['Person1', 'Person3']
      
      big_dict = dict(ChainMap(*data))
      
      # drop duplicates
      people = list(set(people))
      
      smaller_dict = {person: big_dict[person] for person in people}
      

      ChainMap 见here。 我将people 用作列表(而不是集合),因为it has been reported 列表在这些情况下的执行速度稍快。

      【讨论】:

      • 我建议不要使用set() 来更改数据类型,因为您在上面分享的链接和this 所建议的overhead for creating sets can be significant
      • 因为我们只做一次它可能是可以忍受的,特别是如果我们从people 中删除多个条目。如果列表不包含重复项,我们可以确定删除此行。
      • 确实如此。此外,您也可以使用in 来避免这个问题。
      猜你喜欢
      • 2018-04-30
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 2011-01-10
      相关资源
      最近更新 更多