高效过滤字典嵌套列表

2024-04-18 01:42:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个嵌套的字典列表,如下所示:

list_of_dict = [
       {
         "key": "key1",
         "data": [
             {
               "u_key": "u_key_1",
               "value": "value_1"
             },
             {
               "u_key": "u_key_2",
               "value": "value_2"
             }
         ]
       },

       {
         "key": "key2",
         "data": [
             {
                "u_key": "u_key_1",
                "value": "value_3"
             },
             {
               "u_key": "u_key_2",
               "value": "value_4"
             }
         ]
       }
    ]

如您所见,list_of_dict是一个dict列表,其中,data也是一个dict列表。假设list_of_dictdata中的所有对象都具有相似的结构,并且所有键都始终存在。你知道吗

在下一步中,我将list_of_dict转换为list_of_tuples,其中tuple的第一个元素是key,后跟value键内的所有值

list_of_tuples = [
          ('key1', 'value_1'), 
          ('key1', 'value_2'),
          ('key2', 'value_3'), 
          ('key2','value_4')
]

最后一步是与列表进行比较(comparison_list)。列表包含string值。列表中的值可以来自数据中的value键。我需要检查comparison_list内的任何值是否在list_of_tuples内,并获取该值的键(元组的第一项)。你知道吗

comparison_list = ['value_1', 'value_2']

我的预期产出是:

out = ['key1', 'key1']

我的解决方案如下:

  >>> list_of_tuples = [(c.get('key'),x.get('value')) 
               for c in list_of_dict for x in c.get('data')]

  >>> for t in list_of_tuple:
          if t[1] in comparison_list:
              print("Found: {}".format(t[0]))

所以问题的总结是我有一个值列表(comparison_list),我需要在data数组中找到它。你知道吗

我操作的数据集非常庞大(>;100M)。我希望加快我的解决方案,也使它更紧凑和可读性。 我可以跳过创建list_of_tuples的步骤直接进行比较吗?你知道吗


Tags: ofkeyin列表fordatagetvalue
2条回答

您可以尝试以下几种简单的优化:

  • 使comparison_list成为set,因此查找是O(1)而不是O(n)
  • 使list_of_tuples成为生成器,这样就不必一次具体化所有条目
  • 也可以将条件集成到生成器本身中

示例:

comparison_set = set(['value_1', 'value_2'])
tuples_generator = ((c['key'], x['value']) 
                    for c in list_of_dict for x in c['data']
                    if x['value'] in comparison_set)
print(*tuples_generator)
# ('key1', 'value_1') ('key1', 'value_2')

当然,也可以将比较与生成器分开:

tuples_generator = ((c['key'], x['value']) 
                    for c in list_of_dict for x in c['data'])
for k, v in tuples_generator:
    if v in comparison_set:
        print(k, v)

或者您可以创建一个dict映射,将值从comparison_set映射到键从list_of_dicts。这样可以更快地找到特定值的键,但请注意,这样每个值只能保留一个键。你知道吗

values_dict = {x['value']: c['key'] 
               for c in list_of_dict for x in c['data']
               if x['value'] in comparison_set}
print(values_dict)
# {'value_2': 'key1', 'value_1': 'key1'}

在最后一步中,您可以使用这样的过滤器,而不是迭代:

comparison_list = ['value_1', 'value_2']

print(list(filter(lambda x:x[1] in comparison_list,list_of_tuples)))

输出:

[('key1', 'value_1'), ('key1', 'value_2')]

相关问题 更多 >