如何有效地将字典中列表中的项目与第二个字典中另一个列表中的第 0 项进行比较
How to efficiently compare the items in a list within a dictionary to the 0th item within another list within a second dictionary
我有两本字典。一个字典有一个值列表,如下所示:
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)
最明确的方法是:
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"
当然,除了打印它们相等之外,还可以使用 key1
、key2
、val1
和 val2
.
做任何您需要的事情
假设 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)
这是我的做法:
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 调用中拉平迭代器列表。
现在进行实际搜索,我只是检查当前 'key'(索引 0 处的元素)是否在我们来自 d1 的扁平值列表中。
使用您的大型数据集尝试一下,看看它是否比您当前的解决方案更快。
我有两本字典。一个字典有一个值列表,如下所示:
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)
最明确的方法是:
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"
当然,除了打印它们相等之外,还可以使用 key1
、key2
、val1
和 val2
.
假设 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)
这是我的做法:
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 调用中拉平迭代器列表。
现在进行实际搜索,我只是检查当前 'key'(索引 0 处的元素)是否在我们来自 d1 的扁平值列表中。 使用您的大型数据集尝试一下,看看它是否比您当前的解决方案更快。