String search partial dictionary keys within second dictionary keys

Question:

I have two dictionaries:

{'001-002': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0],
 '001-003': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0],
 '001-005': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0]}

{'002-004': [200, 2.5, 250.0, 20.0, -95.0, 80.0, -95.0],
 '003-004': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0],
 '005-004': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0]}

I am trying to create a third dictionary that has all the values if the second number in the first dictionary is the first number in the second dictionary.

ie. match 001-002 and 002-004

i have tried:

for key in destinations.keys():
    if key[0:3] in origins.keys():
        print("yes")

i have also tried:

for key, values in destinations.items():
    if key[0:3] in origins.keys():
        destinations[key] = [destinations[key], origins[keys]]

Desired output:

{'001-002-004': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0, 200, 2.5, 250.0, 20.0, -95.0, 80.0, -95.0]

Asked By: Frank R.

||

Answers:

One solution is to loop through each key value pair in the first, then for each one search for the corresponding pairs in the second dictionary and add the mix of them to the third:

d1 = {'001-002': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0],
 '001-003': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0],
 '001-005': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0]}

d2 = {'002-004': [200, 2.5, 250.0, 20.0, -95.0, 80.0, -95.0],
 '003-004': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0],
 '005-004': [100, 1.5, 150.0, 50.0, -75.0, 60.0, -55.0]}

d3 = {}

for k1, v1 in d1.items():
    key = k1[4:]
    for k2, v2 in d2.items():
        if key == k2[:3]:
            mix = k1[:3] + "-" + k2
            d3[mix] = v1 + v2

However this runs in O(N*M) time, where N is the size of d1 and M d2. Meaning, it’s perfectly fine for when the dictionaries are decently small (up to 5,000 items in each before it gets slow).

It can be done in O(N + M):

mix = {}

for key, val in d2.items():
    new_key = key[:3]
    print(new_key)
    if new_key in mix:
        mix[new_key].append((key[4:], val))
    else:
        mix[new_key] = [(key[4:], val)]

for k1, v1 in d1.items():
    key = k1[4:]
    for k2, v2 in mix[key]:
        d3[k1 + "-" + k2] = v1 + v2

this uses a dictionary mix which acts as a lookup for the first 3 characters in d2. It allows us to immediately retrieve the values without having to search through d2 for every item in d1.

Answered By: felix moeran
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.