简体   繁体   中英

Make dictionary keys to be the same for common values of two different dictionaries

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!

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM