Consider two dictionaries:
dict1 = {'a': 35, 'b': 39, 'c': 20} # (with the values as integers)
dict2 = {'a': 23, 'c': 12}
I want to obtain the following:
dict_new = {'a': 0.657, 'c': 0.6} # (with the values as floats, as values of dict2/dict1)
You can get the common keys using dict2.keys() & dict1 and then just do the division:
dict1 = {'a':35, 'b': 39, 'c':20} #(with the values as integers)
dict2 = {'a':23, 'c':12}
d3 = {k: dict2[k] / dict1[k] for k in dict2.keys() & dict1}
If you want the values rounded to three decimal places use round(dict2[k] / dict1[k],3), if the keys from dict2 should always be in dict1 then you can simply iterate over the items of dict2:
d = {k:v / dict1[k] for k,v in dict2.items()}
dic_new = {}
for key in dic2.keys():
dic_new[key]=float(dict2[key])/dict1[key]
Related
How to perform below operations on two different dictionaries ?
dict2 can be very huge. I believe set operations is bit slower.
get the values of keys of dict1 from dict2, whether same values or different:
dict1 = {'a': 1, 'b': 2}
dict2 = {'a': 3, 'b': 4, 'd': 5}
# Output: {'a': 3, 'b': 4}
dict1 = {'a': 1, 'b': 2}
dict2 = {'a': 1, 'b': 2, 'd': 5}
# Output: {'a': 1, 'b': 2}
key that's present in dict1 but not in dict2, output as shown below
dict1 = {'a': 1, 'b': 2, 'c': 6}
dict2 = {'a': 3, 'b': 4, 'd': 5}
# Output: {'c': 6}
all the keys of dict1 exist in dict2, get values of keys of dict1 from dict2
dict1 = {'a': 1, 'b': 2, 'c': 6}
dict2 = {'a': 3, 'b': 4, 'c': 6, 'd': 5}
# Output: {'a': 3, 'b': 4, 'c': 6}
Tried below methods:
def keys_in_dict1_but_not_in_dict2(dict1, dict2):
d1 = {}
for key in dict1.keys():
if not key in dict2:
d1[key] = dict1[key]
return d1
def keys_in_dict1_and_dict2(dict1, dict2):
d1 = {}
for key in dict1.keys():
if key in dict2:
d1[key] = dict2[key]
return d1
I could have used sets, but that's slower when dictionary length increases. And this above conventional looping may increase the time (along with complexity), as dictionary length increases.
What would be efficient and best way to handle ?
Is this the right approach or any other better approach to handle these scenarios ?
The problem is as follows: iterate through the keys of one dictionary, decide if they are in another, and extract the appropriate values. You can either do both steps in one loop, or separate the key checking from the value extraction. The choice will depend on the number of keys and the number of values you want to copy.
To do the operations together, you would use the loops you show, possibly optimized as comprehensions. To separate out the operations, you would use the fact that dict.keys() returns a set-like view backed by the dictionary itself. This allows you to do selection much faster than converting to a set.
Keys of dict1 that appear in dict2 are dict1.keys() & dict2.keys(). Your two options are therefore
{key: dict2[key] for key in dict1.keys() & dict2.keys()}
AND
{key: dict2[key] for key in dict1 if key in dict2}
Keys of dict1 that don't appear in dict2 are dict1.keys() - dict2.keys(). Your two options are therefore
{key: dict1[key] for key in dict1.keys() - dict2.keys()}
AND
{key: dict1[key] for key in dict1 if key not in dict2}
In this case, no optimization is possible: all the keys need to be iterated over:
{key: dict2[key] for key in dict1}
To find out which option works fastest for 1. and 2., you will have to run a benchmark specific to your data size and ratio of overlap. For example, if len(dict1.keys() & dict2.keys()) < len(dict1), you will save a lot of overhead in __getitem__ by using the first approach for 1. But if most keys are present, then the overhead of doing a set operation on keys() may overtake the computation.
Try using dictionary comprehension.
get the values of keys of dict1 from dict2:
part1 = {key: dict2[key] for key in dict1 if key in dict2}
key that's present in dict1 but not in dict2:
part2 = {key: value for key, value in dict1.items() if key not in dict2}
get values of keys of dict1 from dict2"
part3 = {key: dict2[key] for key in dict1}
This question already has answers here:
Sum corresponding elements of multiple python dictionaries
(4 answers)
Closed 2 years ago.
Suppose I have the following dictionaries:
dict1 = {'a': 10, 'b': 8, 'c':3}
dict2 = {'c': 4}
dict3 = {'e':9, 'a':3}
I'm trying to merge them in a way such that the new (combinational) dictionary contains all the keys and all the values of the same key are added together. For instance, in this case, my desired output looks like:
dict = {'a': 13, 'b': 8, 'c':7, 'e':9}
It looks like the update() method doesn't work since some values are overwritten. I also tried ChainMaps and encountered the same issue. How can I merge multiple dictionaries and add the values of the same key?Thanks a lot:)
Here's a dictionary comprehension to achieve this using itertools.chain.from_iterable() and sum(). Here, I am creating a set of keys from all the three dicts. Then I am iteration over this set inside dictionary comprehension to get the sum of values per key.
>>> from itertools import chain
>>> dict1 = {'a': 10, 'b': 8, 'c':3}
>>> dict2 = {'c': 4}
>>> dict3 = {'e':9, 'a':3}
>>> my_dicts = dict1, dict2, dict3
>>> {k: sum(dd.get(k, 0) for dd in my_dicts) for k in set(chain.from_iterable(d.keys() for d in my_dicts))}
{'a': 13, 'e': 9, 'b': 8, 'c': 7}
This code below should do the trick:
dict1 = {'a': 10, 'b': 8, 'c':3}
dict2 = {'c': 4}
dict3 = {'e':9, 'a':3}
multiple_dict = [dict1, dict2, dict3]
final_dict = {}
for dict in multiple_dict:
for key, value in dict.items():
if key in final_dict:
final_dict[key] += value
else:
final_dict[key] = value
print(final_dict)
I would like to get a new dictionary with keys only if both dictionaries have those keys in them, and then get the values of the second one.
# example:
Dict1 = {'A':3, 'B':5, 'C':2, 'D':5}
Dict2 = {'B':3, 'C':1, 'K':5}
# result--> {'B':3, 'C':1}
As a dictionary comprehension:
>>> {k:v for k, v in Dict2.items() if k in Dict1}
{'B': 3, 'C': 1}
Or use filter:
>>> dict(filter(lambda x: x[0] in Dict1, Dict2.items()))
{'B': 3, 'C': 1}
>>>
Just another solution, doesn't use comprehension. This function loops through the keys k in Dict1 and tries to add Dict2[k] to a new dict which is returned at the end. I think the try-except approach is "pythonic".
def shared_keys(a, b):
"""
returns dict of all KVs in b which are also in a
"""
shared = {}
for k in a.keys():
try:
shared[k] = b[k]
except:
pass
return shared
Dict1 = {'A':3, 'B':5, 'C':2, 'D':5}
Dict2 = {'B':3, 'C':1, 'K':5}
print(shared_keys(Dict1, Dict2))
# >>> {'B': 3, 'C': 1}
I have two following dictionaries with same keys but different values:
dict1 = {"a": [{"b":1, "c":1, "d":[{"e":1, "f":1}]}]}
dict2 = {"a": [{"b":2, "c":2, "d":[{"e":2, "f":2}]}]}
I need to sum these dictionaries and get the following result:
res = {"a": [{"b":3, "c":3, "d":[{"e":3, "f":3}]}]}
How can I do that?
Here is recursive approach:
dict1 = {"a": [{"b":1, "c":1, "d":[{"e":1, "f":1}]}]}
dict2 = {"a": [{"b":2, "c":2, "d":[{"e":2, "f":2}]}]}
def add_objs(d1, d2):
if isinstance(d1, dict):
return {k: add_objs(d1[k], d2[k]) for k in d1}
if isinstance(d1, list):
return [add_objs(a, b) for a, b in zip(d1, d2)]
return d1+d2
add_objs(dict1, dict2)
# {'a': [{'b': 3, 'c': 3, 'd': [{'e': 3, 'f': 3}]}]}
This assumes that d1 and d2 have the exact same inner structure, all dicts have the same keys, all lists the same length, etc.
I have:
myDict = {'a': [1,2,3], 'b':[4,5,6], 'c':[7,8,9]}
I want:
myDict = {'a': set([1,2,3]), 'b':set([4,5,6]), 'c':set([7,8,9])}
Is there a one-liner I can use to do this rather than looping through it and converting the type of the values?
You'll have to loop anyway:
{key: set(value) for key, value in yourData.items()}
If you're using Python 3.6+, you can also do this:
dict(zip(myDict.keys(), map(set, myDict.values())))
This can be done with map by mapping the values to type set
myDict = dict(map(lambda x: (x[0], set(x[1])), myDict.items()))
Or with either version of dictionary comprehension as well
myDict = {k: set(v) for k, v in myDict.items()}
myDict = {k: set(myDict[k]) for k in myDict}
You can use comprehension for it:
Basically, loop through the key-value pairs and create set out of each value for the corresponding key.
>>> myDict = {'a': [1,2,3], 'b':[4,5,6], 'c':[7,8,9]}
>>> myDict = {k: set(v) for k, v in myDict.items()}
>>> myDict
{'a': {1, 2, 3}, 'b': {4, 5, 6}, 'c': {8, 9, 7}}
You can't do it without looping anyway, but you can have the looping done in one line, with the following code:
myDict = {k:set(v) for k, v in myDict.items()}
This is basically traversing each item in your dictionary and converting the lists to sets and combining the key(str):value(set) pairs to a new dictionary and assigning it back to myDict variable.