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
CodePudding user response:
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 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}
CodePudding user response:
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__, ({p[0][0]: p[0][1], p[1][0]: p[1][1]} for p 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
CodePudding user response:
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] = dict1[k1], dict2[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}
CodePudding user response:
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)
CodePudding user response:
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!
CodePudding user response:
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…