获取两个字典中具有相同值的键
我想用Python比较两个字典,主要是找出那些键相同或者说值相同的键。我有两个目标:
- 找出两个字典中值相同的键,
- 找出在另一个字典中没有对应键的键。
我的字典大概长这样:
dict_1={
'3471': ['AY219713', 'AJ504663'], '3460': ['AJ621556', 'AJ575744'], '0': ['AM158981', 'AM158980', 'AM158982', 'AM158979', 'AY594216', 'AY594215', 'EU053207', 'AM392286', 'L26168', 'L37584']}
dict_2 = {'478': ['AY219713', 'AJ504663'], '43': ['AJ575744', 'AJ621556'], '2321': ['AM158979', 'L37584', 'AM158982', 'EU053207', 'AY594215', 'AM392286', 'AY594216', 'L26168', 'AM158981', 'AM158980', 'CP000758', 'AY776289', 'AJ242581', 'AM422370', 'U70978', 'AY457038', 'FR668302', 'AM422371', 'AM490632', 'AM490617', 'AJ242584']}
所以我想得到的结果大概是这样的:
Matching keys from Dictionary 1 and Dictionary 2:
3471 = 478, 2 values in common
3460 = 43, 2 values in common
Keys with no equal match:
Dictionary 1 = 0, etc.
Dictionary 2 = 2321, etc.
那些值不同但键相同的情况不需要考虑。
4 个回答
1
这里有一点有趣的列表推导,使用了 集合
而不是 排序列表
。
for x in [i[0] for i in filter(None,[["%s = %s" %(key1,key2) for key1 in dict_1.keys() if set(dict_1[key1]) == set(dict_2[key2])] for key2 in dict_2.keys()])]:
print x
1
这个方法是通过反转字典,然后遍历一组键(也就是原字典中的值)来实现的。
dict_1 = {
'3471': ['AY219713', 'AJ504663'],
'3460': ['AJ621556', 'AJ575744'],
'0': ['AM158981', 'AM158980', 'AM158982']}
dict_2 = {
'478': ['AY219713', 'AJ504663'],
'43': ['AJ575744', 'AJ621556'],
'2321': ['AM158979', 'L37584', 'AM158982']}
def compare_dicts(D1, D2):
dict_1 = {str(sorted(v)): k for k, v in D1.iteritems()}
dict_2 = {str(sorted(v)): k for k, v in D2.iteritems()}
KEYS = set(dict_1.keys() + dict_2.keys())
both = []
just = {0:[], 1:[]}
for k in KEYS:
Vals = dict_1.get(k, False), dict_2.get(k, False)
if all(map(bool, Vals)):
both.append('{} = {}'.format(*map(str, Vals)))
else:
i = 0 if Vals[0] else 1
just[i].append(Vals[i])
print 'Matching keys from Dictionary 1 and Dictionary 2:'
print '\n'.join(both)
print
print 'Keys with no equal match:'
print 'Dictionary 1 = {}'.format(','.join(map(str, just[0])))
print 'Dictionary 2 = {}'.format(','.join(map(str, just[1])))
compare_dicts(dict_1, dict_2)
这样就能得到我们想要的结果:
Matching keys from Dictionary 1 and Dictionary 2:
3460 = 43
3471 = 478
Keys with no equal match:
Dictionary 1 = 0
Dictionary 2 = 2321
1
使用以下代码:
dict_1={
'3471': ['AY219713', 'AJ504663'], '3460': ['AJ621556', 'AJ575744'], '0': ['AM158981', 'AM158980', 'AM158982', 'AM158979', 'AY594216', 'AY594215', 'EU053207', 'AM392286', 'L26168', 'L37584']}
dict_2 = {'478': ['AY219713', 'AJ504663'], '43': ['AJ575744', 'AJ621556'], '2321': ['AM158979', 'L37584', 'AM158982', 'EU053207', 'AY594215', 'AM392286', 'AY594216', 'L26168', 'AM158981', 'AM158980', 'CP000758', 'AY776289', 'AJ242581', 'AM422370', 'U70978', 'AY457038', 'FR668302', 'AM42237
for k in dict_1:
for i in dict_2:
if sorted(dict_1[k]) == sorted(dict_2[i]):
matches.append((k, i))
for k in matches:
print '%s = %s' %(k[0], k[1])
这段代码运行的结果是:
bash-3.2$ python sortkey.py
3471 = 478
3460 = 43
bash-3.2$
2
这里是对aj8uppal回答的一个小改动——这个版本在匹配和不匹配的定义上更清晰,我觉得结果更接近你想要的。承认这部分是受到aj8uppal的启发;注意我把dict_1
和dict_2
缩短了,以便更易读,而且我只对它们进行了一次排序(当你有5000个键的时候,这一点很重要):
dict_1 = {
'3471': ['AY219713', 'AJ504663'],
'3460': ['AJ621556', 'AJ575744'],
'0': ['AM158981', 'AM158980', 'AM158982']}
dict_2 = {
'478': ['AY219713', 'AJ504663'],
'43': ['AJ575744', 'AJ621556'],
'2321': ['AM158979', 'L37584', 'AM158982']}
match1 = {}
match2 = {}
# sort once: makes a difference when you have lots of elements
for k in dict_1:
dict_1[k] = sorted(dict_1[k])
for j in dict_2:
dict_2[j] = sorted(dict_2[j])
for k in dict_1:
for j in dict_2:
if (dict_1[k] == dict_2[j]):
match1[k]=1
match2[j]=1
break;
print "matching keys:"
print list(match1)
print list(match2)
print "\nnon matching keys:"
print list(set(dict_1.keys()) - set(match1))
print list(set(dict_2.keys()) - set(match2))
这将产生以下输出:
matching keys:
['3471', '3460']
['478', '43']
non matching keys:
['0']
['2321']