0

I have a question regarding merging two dictionaries. It is not a simple merge, but merging in a way that I shall take first key value pair from the first element, then the first element from the second dictionary and so on. For example:



dict1 = {"zero":0,"two":2, "four":4, "six": 6, "eight":8,"ten":10}
dict2 = {"one":1,"three":3,"five":5,"seven":7, "nine":9}

I need to have the following:

dict3 = {"zero":0,"one":1,"two":2,"three":3,"four":4, ... "ten":10 }

Would appreaciate any advise

Anna
  • 11
  • 1

6 Answers6

1

The answer from @Andrei Vintila is along the right lines but dict_keys are not subscriptable and using the smallest size misses some dictionary items. A looping approach which does work (and for any number of elements in either dict) is:

dict1_keys = list(dict1.keys())
dict2_keys = list(dict2.keys())

s1 = len(dict1_keys)
s2 = len(dict2_keys)

max_size = max(s1, s2)

dict3 = {}
for index in range(max_size):
    
    if(index < s1):
        key1 = dict1_keys[index]
        dict3[key1] = dict1[key1]
    if(index < s2):
        key2 = dict2_keys[index]
        dict3[key2] = dict2[key2]

print(dict3)

which produces:

{'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10}
user19077881
  • 3,643
  • 2
  • 3
  • 14
0

You need to create one more dictionary which will merge the other two dictionaries, after that we will only need to sort the new dictionary items. Here is the code:

dict1 = {"zero":0,"two":2, "four":4, "six": 6, "eight":8,"ten":10}
dict2 = {"one":1,"three":3,"five":5,"seven":7, "nine":9}
dict3 = {**dict1, **dict2}
dict3 = dict(sorted(dict3.items(), key=lambda x:x[1]))
print(dict3)
  • thanks, this works, but I am not familliar with lambda function yet, so I am looking to solve it through a simple loop iteration. – Anna Jan 01 '23 at 15:53
0

If you’re on python 3.7+ then the dictionaries maintain the insertion order.

dict1_keys = dict1.keys()
dict2_keys = dict2.keys()

The way you do it is you have to get the keys of the first and second dictionary and loop through them using an index and once you exhaust the keys of one of your dictionaries and still have keys left in the other then you just copy over the remaining keys and values.

smallest_size = min(len(dict1_keys), len(dict2_keys))

for index in range(smallest_size):
   key1 = dict1_keys[index]
   key2 = dict2_keys[index]
   dict3[key1] = dict1[key1]
   dict3[key2] = dict2[key2]

I’m aware this might not be the Python way to tackle this however if you’re brushing up this is one way to do it…

  • Thanks, I believe this is what I am looking for, but it is not clear how to ldo that since when I loop over the first keys, it takes the keys of the first dictionary, but I need to take one from the frist dictionary, then from the second and so on. – Anna Jan 01 '23 at 15:52
  • Hey, I’ve updated the answer. You must find the size of the smallest dictionary and then just copy elements (one time from 1st dict and then the other). Keep in mind that if you have duplicate keys then the value of the second dict will overwrite the first). – Andrei Vintila Jan 01 '23 at 16:16
0

If you want a simple loop approach the key is to use enumerate to get an index you can use to access the second dict (and check you havent run off the end of the second dict - I'm assuming here the second dict is same length or one shorter):

dict1 = {"zero":0,"two":2, "four":4, "six": 6, "eight":8,"ten":10}
dict2 = {"one":1,"three":3,"five":5,"seven":7, "nine":9}

result = {}
keys2 = list(dict2.keys())
for i, k in enumerate(dict1):
  result[k] = dict1[k]
  if i < len(dict2):
    result[keys2[i]] = dict2[keys2[i]]

If you wanted a more functional approach you could do this:

from functools import reduce
result = reduce(dict.__or__, ({k1: v1, k2: v2} for (k1, v1), (k2, v2) in zip(dict1.items(), dict2.items())))

which works fine if both dicts are the same length. If the second is shorter, you'll need to manually append the remaining key-value from the first dict afterwards

virgesmith
  • 762
  • 1
  • 7
  • 18
0

Simple iteration with zip(). However zip() only return the shortest argument of iterable. In this case, the last key:value of the longest dict will not be included. dict.update() will update the dict to ensure all keys and values are added:

dict1 = {"zero":0,"two":2, "four":4, "six": 6, "eight":8,"ten":10}
dict2 = {"one":1,"three":3,"five":5,"seven":7, "nine":9, "eleven":11, "twelve":12}

dict3 = {}
for k1, k2 in zip(dict1, dict2):
    dict3[k1], dict3[k2] = k1, k2
dict3.update(dict1); dict3.update(dict2)

print(dict3)

# {'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10, 'eleven': 11, 'twelve': 12}
Arifa Chan
  • 947
  • 2
  • 6
  • 23
-1

So dictionaries are not sequences like a list (as despite being "ordered" since 3.7, in most cases the order doesn't matter ). There is such a thing as an ordered dictionary from the collections module

There are several ways to combine dictionaries

The easiest way in your case is .update() so:

dict1.update(dict2)

To merge all the keys/val pairs into one dictionary

You can also use kwargs:

dict3 = {**dict1, **dict2}

If you still want them sorted you can use the sorted with different function

sorted(dict3,key=[insert]) # note can also use reverse=True

Different key functions: str: if an increasing name like a,b,c etc lamda x: dict3[x]: if increase value such as 0,1,2,3 etc

could also make a key list and search from that (though a bit more hacky)

key_list =[]
#Note only works if len(dict1) = len(dict2)
for item1, item2 in zip(dict1,dict2): 
    key_list.extend([item1,item2])

And then do key=lambda x: key_list.index(x)

Hope this helps!