【问题标题】:Optimizing code to get keys of matching values in two dictionaries优化代码以获取两个字典中匹配值的键
【发布时间】:2020-10-30 03:33:13
【问题描述】:

我正在寻找一种方法来提高我的代码性能:给定两个字典,我需要找到匹配值对的键。到目前为止,我正在迭代这两个字典,当它们都有多达 100000 个键值对时,这将非常慢。

给定:

  • 两个字典的键始终是数字并按升序排序
  • 两个字典的键都是指我需要使用的 QGIS 层的特征,所以我真的需要保持这种方式
  • 两个字典的值可以有任何数据类型,但总是有相同的数据类型
  • 两个字典的值都是随机填充的
  • 值可以包含不能删除的重复项

有没有人知道如何提高性能?请注意,如果有充分根据,“不,绝对不可能”也是一个可以接受的答案,所以我终于可以停止尝试和搜索了。

dict_a = {1:'abc',2:'def',3:'abc',4:'ghj',5:'klm',6:'nop',7:'def',8:'abc',9:'xyz',10:'abc'}
dict_b = {1:'abc',2:'a',3:'b',4:'xyz',5:'abc',6:'b',7:'c',8:'def',9:'d',10:'e'}
# imagine both dictionaries have up to 100000 entries...

desired_matching_dict = {1:1,1:5,2:8,3:1,3:5,7:8,8:1,8:5,9:4,10:1,10:5} # example of my desired output
matching_dict_slow = {}
matching_dict_fast = {}

# This will be very slow when having huge dictionaries...
for key_a, value_a in dict_a.items():
    for key_b, value_b in dict_b.items():
        if value_a == value_b:
            matching_dict_slow[key_a] = key_b

# Seeking an attempt to speed this up
# But getting lost...
for key, value in dict_a.items():
    if value in dict_b.items():
        if dict_a[key] == dict_b[key]:
            matching_dict_fast[key]=dict_a[key]

print('Slow method works: ' + str(desired_matching_dict == matching_dict_slow))
print('Fast method works: ' + str(desired_matching_dict == matching_dict_fast))

【问题讨论】:

  • 您的desired_matching_dict 有重复的密钥,这是不允许的。重复键的值将被第二个覆盖。您想如何处理来自dict_b 的密钥1 和密钥5 与来自dict_a 的密钥1 相同的情况?
  • 您如何切换键/值?值不是唯一的,但键必须是唯一的。
  • @Adamantoisetortoise 好点,那么它不可能,我删除它。 [at]Michael 好问题,我真的需要保留这些,因为实际上它们指的是我需要使用的功能
  • @MrXsquared 你试过答案中提到的方法吗?

标签: python dictionary optimization


【解决方案1】:

从我通常面临的竞争性编程用途来看,这种简单的方法应该可以正常工作:

dict_a = {1:'abc',2:'def',3:'abc',4:'ghj',5:'klm',6:'nop',7:'def',8:'abc',9:'xyz',10:'abc'}
dict_b = {1:'abc',2:'a',3:'b',4:'xyz',5:'abc',6:'b',7:'c',8:'def',9:'d',10:'e'}

dic2 = {}
for i in dict_b.keys():
    elem = dict_b[i]
    if dic2.get(elem, None):
        dic2[elem].append(i)
    else:
        dic2[elem] = [i]
matches = {}
for i in dict_a.keys():
    elem = dict_a[i]
    x = dic2.get(elem, None)
    if x:
        matches[i] = x 

print(matches) #prints {1: [1, 5], 2: [8], 3: [1, 5], 7: [8], 8: [1, 5], 9: [4], 10: [1, 5]}

然后您可以访问您的功能,例如:

for k, v in matches.items():
    l = len(v) - 1
    i = 0
    for l in v:
        print('desired pair: ' + 'key (dict_a feature) = ' + str(k) + ' | value(dict_b feature) = ' + str(v[i]))
        i += 1

【讨论】:

    【解决方案2】:
    def dict_gen(a, b):
        for i in a:
            res = []
            for j in b:
                if a[i] == b[j]:
                    res.append(j)
            if res:
                yield [(i), res]
    
    d = dict(i for i in dict_gen(dict_a, dict_b))
    print(d)
    

    输出:

    {1: [1, 5], 2: [8], 3: [1, 5], 7: [8], 8: [1, 5], 9: [4], 10: [1, 5]}
    [Finished in 0.1s]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      相关资源
      最近更新 更多