我有一个列表,其中包含一定数量的词典,我必须将其与另一个词典进行比较。
它们具有以下形式(键和值没有特定的形式或模式,这些是随机选择的示例):
list1 = [
{'X1': 'Q587', 'X2': 'Q67G7', ...},
{'AB1': 'P5K7', 'CB2': 'P678', ...},
{'B1': 'P6H78', 'C2': 'BAA5', ...}]
dict1 = {
'X1': set([B00001,B00020,B00010]),
'AB1': set([B00001,B00007,B00003]),
'C2': set([B00001,B00002,B00003]), ...
}
我现在想要的是一个新词典,其中包含以下键:list1中词典的值。以及dict1的值作为值。只有当键在比较的词典中相交时才会这样。
我已通过以下方式完成此操作:
nDicts = len(list1)
resultDict = {}
for key in range(0,nDicts):
for x in list1[key].keys():
if x in dict1.keys():
resultDict.update{list1[key][x]:dict1[x]}
print resultDict
所需的输出应采用以下形式:
resulDict = {
'Q587': set([B00001,B00020,B00010]),
'P5K7': set([B00001,B00007,B00003]),
'BAA5': set([B00001,B00002,B00003]), ...
}
这样可行,但由于数据量太高,这需要永远。 有更好的方法吗?
编辑:我稍微更改了输入值,唯一重要的是在list1中的字典和dict1中的字典之间相交的键。答案 0 :(得分:1)
Python 2.x中的keys
方法创建了一个包含所有键的副本的列表,并且您不仅对list1
中的每个词都执行此操作(可能不是什么大不了的事) ,但是在不知道你的数据的情况下很难确定,但也一遍又一遍地为dict1
做这件事。
最重要的是,对列表进行in
测试需要很长时间,因为它必须检查列表中的每个值,直到找到匹配项,但是对in
进行keys
测试字典几乎是即时的,因为它只需要查找哈希值。
两个keys()
实际上是完全不必要的 - 迭代dict按顺序为你提供键(一个未指定的顺序,但调用in
时也是如此)和keys()
- 检查dict搜索for key in range(0,nDicts):
for x in list1[key]:
if x in dict1:
resultDict={list1[key][x]:dict1[x]}
print resultDict
获得的相同密钥。因此,删除它们会做同样的事情,但更简单,更快速,并且使用的内存更少。所以:
list1
还有一些方法可以简化这一点,可能无法帮助提高性能,但仍然值得做。
您可以直接在for list1_dict in list1:
for x in list1_dict:
if x in dict1:
resultDict = {list_dict[x]: dict1[x]}
print resultDict
上进行迭代,而不是构建所有索引的大量列表并迭代它。
for list1_dict in list1:
for k, v in list1_dict.iteritems():
if k in dict1:
resultDict = {v: dict1[k]}
print resultDict
您只需一步即可获得密钥和值:
for list1_dict in list1:
for k, v in list1_dict.iteritems():
try:
resultDict = {v: dict1[k]}
print resultDict
except KeyError:
pass
此外,如果您希望找到大多数值,首先检查该值需要大约两倍的时间,然后查找它,因为它只是尝试查找并处理失败。 (但是,如果找不到大多数值 ,则情况并非如此。)所以:
{{1}}
答案 1 :(得分:1)
您可以使用设置的交叉点简化和优化您的操作;从Python 2.7开始,字典可以使用dict.viewkeys()
方法将键表示为集合,或者在Python 3中表示dict.keys()
:
resultDict = {}
for d in list1:
for sharedkey in d.viewkeys() & dict1:
resultDict[d[sharedkey]] = dict1[sharedkey]
这甚至可以变成一个词典理解:
resultDict = {d[sharedkey]: dict1[sharedkey]
for d in list1 for sharedkey in d.viewkeys() & dict1}
我假设你想要一个结果字典,而不是每个共享密钥的新字典。
示例输入演示:
>>> list1 = [
... {'X1': 'AAA1', 'X2': 'BAA5'},
... {'AB1': 'AAA1', 'CB2': 'BAA5'},
... {'B1': 'AAA1', 'C2': 'BAA5'},
... ]
>>> dict1 = {
... 'X1': set(['B00001', 'B00002', 'B00003']),
... 'AB1': set(['B00001', 'B00002', 'B00003']),
... }
>>> {d[sharedkey]: dict1[sharedkey]
... for d in list1 for sharedkey in d.viewkeys() & dict1}
{'AAA1': set(['B00001', 'B00002', 'B00003'])}
请注意,X1
和 AB1
都与list1
中的词典共享,但在这两种情况下,生成的密钥都为AAA1
。其中只有一个获胜(最后一场比赛),但由于dict1
中的两个值完全相同,因此在这种情况下不会产生任何赔率。
如果您想在list1
中为每个字典添加单独的词典,只需将for d in list1:
循环移出:
for d in list1:
resultDict = {d[sharedkey]: dict1[sharedkey] for sharedkey in d.viewkeys() & dict1}
if resultDict: # can be empty
print resultDict
如果您真的想要每个共享密钥使用一个字典,请移出另一个循环:
for d in list1:
for sharedkey in d.viewkeys() & dict1:
resultDict = {d[sharedkey]: dict1[sharedkey]}
print resultDict
答案 2 :(得分:0)
#!/usr/bin/env python
list1 = [
{'X1': 'AAA1', 'X2': 'BAA5'},
{'AB1': 'AAA1', 'CB2': 'BAA5'},
{'B1': 'AAA1', 'C2': 'BAA5'}
]
dict1 = {
'X1': set(['B00001','B00002','B00003']),
'AB1': set(['B00001','B00002','B00003'])
}
g = ( k.iteritems() for k in list1)
ite = ((a,b) for i in g for a,b in i if dict1.has_key(a))
d = dict(ite)
print d