serendipity
serendipity

Reputation: 862

Compare two dictionaries with one key in common and form a new dictionary combining the remaining keys associated with this common key

I have two dictionaries, one contains the name and initial values of some registers and the other contains the name and address values of those same registers.

I need to compare the two dictionaries on register names [id] and then take the initial value of a register [initValue] from dictionary 1 and the address values [addrValue] from dictionary 2 and put them in a new dictionary so that the key in this new dictionary becomes the address rather than the register name.

Below is what I am doing but I don't know how to merge the two dictionary keys.

regex = "(?P<id>\w+?)_INIT\s*?=.*?'h(?P<initValue>[0-9a-fA-F]*)"
for x in re.findall(regex, lines):
    init_list = (x.groupdict()["id"], "0x" + x.groupdict()["initValue"])

regex = "(?P<id>\w+?)_ADDR\s*?=.*?'h(?P<addrValue>[0-9a-fA-F]*)"
for y in re.findall(regex, lines):
    addr_list = (y.groupdict()["addr_id"], "0x" + y.groupdict()["addrValue"])

for key in set(init_list['init_id'].keys()).union(addr_list['id'].keys()):
    if init_list[key] == addr_list[key]
        expect_by_addr = dict (addr_list['addrValue']   # something here

Upvotes: 1

Views: 1287

Answers (3)

Francis Avila
Francis Avila

Reputation: 31641

Why don't you build a single dict in a single pass?

from collections import defaultdict

r_line = re.compile(r"(?P<id>\w+?)_(?P<type>[A-Z]+)\s*?=.*?'h(?P<value>[0-9a-fA-F]*)")

register_ids = defaultdict(dict)

for match in r_line.finditer(lines):
    groups = match.groupdict()
    key = groups['type'].tolower()
    # store as int. You can use `hex()` or format codes for display as hex
    value = int(groups['value'], 16)
    register_ids[groups['id']][key] = value

It's not a problem if you have multiple sets of lines: it will just update register_ids with new data:

for lines in lines_list:
    for match in r_line.finditer(lines):
        ...

This will produce a single dict ids that looks like this:

{'register1': {'addr': 1234, 'init': 5678, ...}, 'register2': {...}, ...}

You can then produce any other kind of derived dictionary you want very easily. For example, for your initial values keyed by addresses:

addresses = {}
for values in register_ids.itervalues():
    try:
        addresses[values['addr']] = values['init']
    except KeyError:
        pass

Upvotes: 2

rdp
rdp

Reputation: 2745

Make the first two dictionaries:

dict1 = {}
dict2 = {}
for x in range(0, 10):
    dict1[x] = "initValue{}".format(x)
    y = x+3
    dict2[y] = "address{}".format(y)

Combine them based on dict2 "addresses"

dict3 = {}
#Note because you want the addresses to be the key of the new dictionary
#we only need to look at the keys that exist in both dict1 and dict2.
for key in dict2.keys():
    if key in dict1:
        dict3[dict2[key]] = dict1[key]

Dictionaries:

dict1
{0: 'initValue0', 1: 'initValue1', 2: 'initValue2', 3: 'initValue3', 4: 'initValue4', 5: 'initValue5', 6: 'initValue6', 7: 'initValue7', 8: 'initValue8', 9: 'initValue9'}

dict2
{3: 'address3', 4: 'address4', 5: 'address5', 6: 'address6', 7: 'address7', 8: 'address8', 9: 'address9', 10: 'address10', 11: 'address11', 12: 'address12'}

dict3 (combined)
{'address5': 'initValue5', 'address4': 'initValue4', 'address7': 'initValue7', 'address6': 'initValue6', 'address3': 'initValue3', 'address9': 'initValue9', 'address8': 'initValue8'}

Upvotes: 1

Inbar Rose
Inbar Rose

Reputation: 43487

I am not sure what the code is related to your question.

But let us assume you have two dicts. dictA and dictB (below are example dicts):

>>> dictA = dict.fromkeys(range(10), {'initial_val_1': 'value_a', 'initial_val_2': 'value_b' })
>>> dictB = dict.fromkeys(range(5, 15), {'address': 'my_address'})

Code you need:

>>> from collections import defaultdict
>>> shared_keys = set(dictA.keys()).intersection(set(dictB.keys()))
>>> combined = defaultdict(dict)
>>> for key in shared_keys:
    combined[key].update(dictA[k])
    combined[key].update(dictB[k])

View the dictionary:

>>> for k, v in combined.items():
    print k, v

5 {'initial_val_2': 'value_b', 'initial_val_1': 'value_a', 'address': 'my_address'}
6 {'initial_val_2': 'value_b', 'initial_val_1': 'value_a', 'address': 'my_address'}
7 {'initial_val_2': 'value_b', 'initial_val_1': 'value_a', 'address': 'my_address'}
8 {'initial_val_2': 'value_b', 'initial_val_1': 'value_a', 'address': 'my_address'}
9 {'initial_val_2': 'value_b', 'initial_val_1': 'value_a', 'address': 'my_address'}

Upvotes: 1

Related Questions