加速将字典键和值与 python 列表中的字符串进行比较

accelerate comparing dictionary keys and values to strings in list in python

抱歉,如果这是微不足道的,我还在学习,但我有一个字典列表,如下所示:

[{'1102': ['00576', '00577', '00578', '00579', '00580', '00581']},
 {'1102': ['00582', '00583', '00584', '00585', '00586', '00587']},
 {'1102': ['00588', '00589', '00590', '00591', '00592', '00593']},
 {'1102': ['00594', '00595', '00596', '00597', '00598', '00599']},
 {'1102': ['00600', '00601', '00602', '00603', '00604', '00605']}
 ...]

它包含 ~89000 部词典。我有一个包含 4473208 条路径的列表。示例:

['/****/**/******_1102/00575***...**0CT.csv',
'/****/**/******_1102/00575***...**1CT.csv',
'/****/**/******_1102/00575***...**2CT.csv',
'/****/**/******_1102/00575***...**3CT.csv',
'/****/**/******_1102/00575***...**4CT.csv',
'/****/**/******_1102/00578***...**1CT.csv',
'/****/**/******_1102/00578***...**2CT.csv',
'/****/**/******_1102/00578***...**3CT.csv',
 ...]

我想要做的是将包含密钥的文件夹中的字典中包含分组值的每个路径分组在一起。

我试过像这样使用 for 循环:

grpd_cts = []
   
for elem in tqdm(dict_list):
    temp1 = []
    for file in ct_paths:
        for key, val in elem.items():
            if (file[16:20] == key) and (any(x in file[21:26] for x in val)):
                temp1.append(file)

    grpd_cts.append(temp1)

但这需要大约 30 个小时。有没有办法让它更有效率?任何 itertools 功能或什么?

非常感谢!

ct_paths 在你的内部循环中重复迭代,你只对它的一点点感兴趣用于测试目的;把它拿出来,用它来索引你的其余数据,作为字典。

使您的问题复杂化的是您想要以 原始 文件名列表结束,因此您需要构造一个 two-level 字典,其中这些值是在这两个键下分组的所有原件的列表。

ct_path_index = {}
for f in ct_paths:
    ct_path_index.setdefault(f[16:20], {}).setdefault(f[21:26], []).append(f)

grpd_cts = []
for elem in tqdm(dict_list):
    temp1 = []
    for key, val in elem.items():
        d2 = ct_path_index.get(key)
        if d2:
            for v in val:
                v2 = d2.get(v)
                if v2:
                    temp1 += v2
    grpd_cts.append(temp1)

ct_path_index 看起来像这样,使用您的数据:

{'1102': {'00575': ['/****/**/******_1102/00575***...**0CT.csv',
   '/****/**/******_1102/00575***...**1CT.csv',
   '/****/**/******_1102/00575***...**2CT.csv',
   '/****/**/******_1102/00575***...**3CT.csv',
   '/****/**/******_1102/00575***...**4CT.csv'],
  '00578': ['/****/**/******_1102/00578***...**1CT.csv',
   '/****/**/******_1102/00578***...**2CT.csv',
   '/****/**/******_1102/00578***...**3CT.csv']}}

setdefault(第一次看到时可能有点难以理解)的使用在构建集合集合时很重要,并且在这些情况下很常见:它使确保 sub-collections 是按需创建的,然后是给定键的 re-used。

现在,您只有两个嵌套循环;内部检查是使用字典查找完成的,接近于 O(1)。

其他优化包括将 dict_list 中的列表转换为集合,如果您多次通过 dict_list.

,这将是值得的