Reputation: 23
I have two dictionaries dic1 and dic2 which have common values but different keys. For example:
dic1 = {'M_001': 'gly-glu-L', 'M_002': 'Ala-Gln'}
dic2 = {'M_003': 'gly-glu-L', 'M_004': 'Ala-Gln'}
I used the following code to retrive the common values between the two:
match = []
for value1 in dic1.values():
for value2 in dic2.values():
if value1 == value2:
match.append(value1)
Next, for each common value in both dictionaries, I want to have the same keys.
First bjective:
dic1 = {'M_003': 'gly-glu-L', 'M_004': 'Ala-Gln'}
dic2 = {'M_003': 'gly-glu-L', 'M_004': 'Ala-Gln'}
Second objective with unique identifiers:
dic1 = {'MX_001': 'gly-glu-L', 'MX_002': 'Ala-Gln'}
dic2 = {'MX_001': 'gly-glu-L', 'MX_002': 'Ala-Gln'}
I need some intel on how to proceed because I am stuck at this stage.
Thank you!
Upvotes: 0
Views: 53
Reputation: 1771
def tmp(d1, d2):
# create 2 new dicts where the key and values are reversed
rd1 = dict((v,k) for k,v in d1.items())
rd2 = dict((v,k) for k,v in d2.items())
for v in set(rd1.keys()) & set(rd2.keys()):
# cycle over the common values
del d1[rd1[v]] # delete the old_key from the first dict
d1[rd2[v]] = v # set the value with the same key as the second one
def tmp2(d1, d2):
# solution for a "multiple key, same value in first dict" situation
rd1 = {}
for k,v in d1.items():
if v not in rd1: # could use a defaultdict to avoid this
rd1[v] = []
rd1[v].append(k)
rd2 = dict((v,k) for k,v in d2.items())
for v in set(rd1.keys()) & set(rd2.keys()):
for k in rd1[v]: # delete all the (old) keys
del d1[k]
d1[rd2[v]] = v
from random import randrange
def tmp3(d1, d2):
rd1 = {}
for k,v in d1.iteritems():
if v not in rd1:
rd1[v] = []
rd1[v].append(k)
rd2 = dict((v,k) for k,v in d2.iteritems())
for v in set(rd1.keys()) & set(rd2.keys()):
for k in rd1[v]:
del d1[k]
while 1:
# attention here: if you'd have more than 100 new keys you'll end up with an infinite loop, adjust for your case
# I've used 100 to maintain the 3 digit format
new_key = "MX_%03d" % randrange(100)
if new_key not in d1: break
d1[new_key] = v
def tmp4(d1, d2):
# solution for your final form of the second objective
# please stop changing the question :D
rd1 = {}
for k,v in d1.iteritems():
if v not in rd1:
rd1[v] = []
rd1[v].append(k)
rd2 = {}
for k,v in d2.iteritems():
if v not in rd2:
rd2[v] = []
rd2[v].append(k)
for i, v in enumerate(set(rd1.keys()) & set(rd2.keys())):
for k in rd1[v]:
del d1[k]
for k in rd2[v]:
del d2[k]
new_key = "MX_%03d" % i # nothimg more random than counter, see: https://xkcd.com/221/
d1[new_key] = v
d2[new_key] = v
dic1 = {'M_001': 'gly-glu-L', 'M_002': 'Ala-Gln'}
dic2 = {'M_003': 'gly-glu-L', 'M_004': 'Ala-Gln'}
if __name__ == '__main__':
print dic1
print dic2
tmp(dic1,dic2)
print
print dic1
print dic2
gives
{'M_001': 'gly-glu-L', 'M_002': 'Ala-Gln'}
{'M_004': 'Ala-Gln', 'M_003': 'gly-glu-L'}
{'M_004': 'Ala-Gln', 'M_003': 'gly-glu-L'}
{'M_004': 'Ala-Gln', 'M_003': 'gly-glu-L'}
might have issues if you have multiple keys with the same value that would need a different approach.
Upvotes: 1
Reputation: 33
If you don't want to create additional inverted copies, you can make a separate list and dictionary to do the task as follows :
def comun(dict1, dict2):
# get common information
emptyDict = {}
removeList = []
for d1key, d1val in dict1.items():
for d2key, d2val in dict2.items():
if (d1val == d2val):
removeList.append(d1key)
emptyDict[d2key] = d2val
break
# remove repeated elements
for item in removeList:
del dict1[item]
# add common elements
dict1.update(emptyDict)
dict1 = {'M_001': 'gly-glu-L', 'M_002': 'Ala-Gln'}
dict2 = {'M_003': 'gly-glu-L', 'M_004': 'Ala-Gln'}
if __name__ == '__main__':
print(dict1)
print(dict2)
comun(dict1,dict2)
print(dict1)
print(dict2)
Upvotes: 0