如何有效地将字典中列表中的项目与第二个字典

时间:2015-07-25 18:22:48

标签: python list dictionary comparison

我有两本词典。一个字典有一个值列表,如下所示:

d1 = {10: [123, 244, 222], 13: [109, 125]}

在这本词典中,大多数情况下列表中只有一个项目,但有一些项目包含多个值。

第二个字典也有一个值列表。但是对于此列表中的每个值,都有多个值。基本上我的第二个字典包含一个列表列表,如下所示:

d2 = {125: [[120, 244, 222], [177, 134, 111], [123, 11, 344]], 123: [[125, 109, 180], [123, 156, 290]]}

我尝试做的是有效地将d1中的所有值与位置0中的所有值进行比较,针对d2中所有键中的每个列表。

例如,我想将d1中的每个值与d2: (120, 177, 123, 125, 123)的以下值进行比较,因为它们代表所有列表中的第0个值。然后,我想存储其第0个值与d1中的值匹配的列表。

由于某些原因,索引并不适合我。我一直在尝试这个:

 for key, value in d1.iteritems():                                           
     for list in value:                                                                                      
         for key, value2 in d2.iteritems():                
             for item2 in value2:  
                 if list == item2[0]:        
                     d3[item2[0]].append(item2[0:])

获得此输出:

defaultdict(<type 'list'>, {125: [[125, 109, 180]], 123: [[123, 11, 344], [123, 156, 290]]})

但是我在这个例子中使用的词典比我的实际词典要小得多。一个拥有数十万行数据,另一个拥有数百万个数据。

我还没有将其纳入我的代码中,只有当它们具有匹配的密钥时才会遍历密钥。

我开始使用类似的东西:

for key in d1.iterkeys() and d2.iterkeys():

但是使用以下内容遇到了问题:

if d1[key][:] == d2[key][:][:][0]

因为列表清单存在问题。这部分非常令人沮丧。如果我可以迭代而不必显式使用上面显示的代码的这部分(对于列表值:)并且只是做一个值索引,它会节省我相信的时间。但索引并没有为我工作。例如,使用d2[key][:][:][0],我总是得到(特别是我的第二个字典)键中的第一个列表,而不是键中每个列表的第一个值。

编辑:在我得到以下两个答案的更新之前,我在这里使用此代码,这与我的初始代码基本相同,除了我已添加条件语句,我检查到看看钥匙是否相等。在增加搜索速度方面添加条件语句是否有意义?我不知道添加if语句是否会减慢速度,而只是搜索密钥匹配的位置会加快速度。

for key1, value1 in d1.iteritems():                                           
     for item1 in value1:                                                                                      
         for key2, value2 in d2.iteritems():  
             if key1 == key2:              
                 for item2 in value2:  
                     if list == item2[0]:        
                         d3.append(item2) 

3 个答案:

答案 0 :(得分:0)

最明确的方法是:

d1 = {10: [123, 244, 222], 13: [109, 125]}

d2 = {125: [[120, 244, 222], [177, 134, 111], [123, 11, 344]], 123: [[125, 109, 180], [123, 156, 290]]}

for key1 in d1:
    for val1 in d1[key1]:
        for key2 in d2:
            for vals2 in d2[key2]:
                 val2 = vals2[0]
                 if val1 == val2:
                     print "equal"

当然,与key1key2val1val2无关,只需打印相同的内容即可。

答案 1 :(得分:0)

假设d2的值都是列表的列表

d1 = {10: [123, 244, 222], 13: [109, 125]}
d2 = {125: [[120, 244, 222], [177, 134, 111], [123, 11, 344]], 123: [[125, 109, 180], [123, 156, 290]]}

d1Flat = [i for item in d1.values() for i in item]
d2Flat = [i for item in d2.values() for i in item]

res = []

for lst in d2Flat:
    if lst[0] in d1Flat:
        res.append(lst)

答案 2 :(得分:0)

以下是我的观点:

from itertools import chain

d1 = {10: [123, 244, 222], 13: [109, 125]}
d2 = {125: [[120, 244, 222], [177, 134, 111], [123, 11, 344]], 123: [[125, 109, 180], [123, 156, 290]]}

# Flatten out the list using a list comprehension
key_values = [values for list in d1.values() for values in list]

new_dict = dict()
for d2_list in chain.from_iterable(d2.itervalues()):
    key_to_check = d2_list[0]
    if key_to_check in key_values:
        if key_to_check in new_dict:
            new_dict[key_to_check].append(d2_list)
        else:
            new_dict[key_to_check] = [d2_list]
print new_dict

由于我们只使用迭代器循环遍历第二个字典的值,因此至少应该更快一些。 我使用chain.from_iterable来平衡itervalues调用中的迭代器列表。

现在进行实际搜索,我只检查当前的关键字&#39; (索引0处的元素)在我们的d1值的展平列表中。 尝试使用您的大型数据集,看看它是否比您当前的解决方案更快。