Comparing the values of two dictionaries to receive their numerical difference Python - python

I am new to Python. I have two dictionaries which share the same keys but different values for the keys. I would like to compare the two dictionaries so that I would get the numerical difference of the values for each key. For example:
dict1 = {'hi' : 45, 'thanks' : 34, 'please' : 60}
dict2 = {'hi' : 40, 'thanks' : 46, 'please' : 50}
In other words, I would like to receive a third dictionary or a list of pairs that would show the numerical difference of the values within these two dictionaries (i.e.subtracting the values of dict1 from dict2 (or vice versa). It would thus be something like this:
dict_difference = {'hi' : 5 , 'thanks' : -12, 'please' : 10}
I know that subtracting one dictionary from another by :
dict1 = Counter({'hi' = 45, 'thanks' = 34, 'please' = 60})
dict2 = Counter({'hi' = 40, 'thanks' = 46, 'please' = 50})
dict3 = dict1-dict2 # will only return the positive values so it will give:
dict3 = {'hi'= 5, 'please' = 10} # which is NOT what I want.
I also thought of converting the dictionaries into a list of pairs (I think this is how it is called) :
dictlist = []
for key, value in dict1.iteritems():`
temp = (key, value)
dictlist.append(temp)
and therefore
print dictlist #gives:
[('hi', 45),('thanks' = 34), ('please' = 60)]
So I thought that if I can manage to convert the dictionary into the list of pairs and then to make it in the form of the key:value to be key = value I would be able to apply the subtract() method and achieve what I want.
I thought of achieving it through the def __repr__(self) as shown in https://docs.python.org/2/library/collections.html but I didn't get far.
I would be most grateful for any help. Please, if possible leave description for your code. If my approach is wrong and there is an easier way of subtracting the values of one dictionary from another please share it as well.

First, the format of your dictionaries is not correct (: and not =):
dict1 = {'hi':45, 'thanks':34, 'please':60}
dict2 = {'hi':40, 'thanks':46, 'please':50}
You can use a dictionary comprehension. You basically loop through one dictionary, check that the key is also in the second dictionary and insert the difference of the values in the output dictionary. All in one line.
dic = {key: dict1[key]-dict2[key] for key in dict1 if key in dict2}

You were on the right path with thinking about using the dictionarys' keys.
Here, I go through the first dictionary's keys, checking if they're in dictionary2. Then I do the same with dictionary2, checking for keys in dictionary1, but also ensuring that the key isn't already in the result dictionary so we don't do duplicate subtraction.
dict1 = {'hi': 45, 'thanks': 34, 'please': 60}
dict2 = {'hi': 40, 'thanks': 46, 'please': 50}
result = {}
for key in dict1.keys():
if key in dict2:
result[key] = dict1[key] - dict2[key]
for key in dict2.keys():
if key in dict1 and not key in result:
result[key] = dict1[key] - dict2[key]

Related

Convert a list with duplicating keys into a dictionary and sum the values for each duplicating key

I am new to Python so I do apologize that my first question might not be asked clearly to achieve the right answer.
I thought if I converted a list with duplicating keys into a dictionary then I would be able to sum the values of each duplicating key. I have tried to search on Google and Stack Overflow but I actually still can't solve this problem.
Can anybody help, please? Thank you very much in advance and I truly appreciate your help.
list1 = ["a:2", "b:5", "c:7", "a:8", "b:12"]
My expected output is:
dict = {a: 10, b: 17, c: 7}
You can try this code:
list1 = ["a:2", "b:5", "c:7", "a:8", "b:12"]
l1 = [each.split(":") for each in list1]
d1 = {}
for each in l1:
if each[0] not in d1:
d1[each[0]] = int(each[1])
else:
d1[each[0]] += int(each[1])
d1
Output: {'a': 10, 'b': 17, 'c': 7}
Explanation:
Step 1. Convert your given list to key-value pair by splitting each of the elements in your original list from : and store that in a list/tuple
Step 2. Initialize an empty dictionary
Step 3. Iterate through each key-value pair in the newly created list/tuple and store that in a dictionary. If the key doesn't exist, then add new key-value pair to dictionary or else just add the values to it's corresponding key.
A list does not have "keys" per say, rather it has elements. In your example, the elements them selves are a key value pair. To make the dictionary you want you have to do 3 things,
Parse each element into its key value pair
Handle duplicate values
Add each pair to the dictionary.
the code should look like this
list1 = ["a:2", "b:5", "c:7", "a:8", "b:12"]
dict1={}#make an empty dictionary
for element in list1:
key,value=element.split(':')#This splits your list elements into a tuple of (key,value)
if key in dict1:#check if the key is in the dictionary
dict1[key]+=int(value)#add to existing key
else:
dict1[key]=int(value)#initilize new key
print(dict1)
That code prints out
{'a': 10, 'c': 7, 'b': 17}
You could use a defaultdict, iterate over each string and add the corresponding value after splitting it to a pair (key, value).
>>> from collections import defaultdict
>>> res = defaultdict(int)
>>> for el in list1:
... k, v = el.split(':')
... res[k]+=int(v)
...
>>> res
defaultdict(<class 'int'>, {'a': 10, 'b': 17, 'c': 7})

Python: How to iterate through a dictionary using a list, instead of counter

I have a dictionary with the following structure:
results =
{1: {'A': 10,
'B' : 11,
'C': 12},
5: {'A': 20,
'B' : 21,
'C': 22}}
I have tried to iterate through this dictionary using this for loop:
total_A = []
for key in results:
total_A.append(results[key]["A"])
print total_A
But it is not working, because it is inputting key as 1 and 2 each time it loops. How am i able to iterate through the results dictionary using index as 1 and 5? (they are of type integer)
Try this. It will loop through your dictionary keys.
for key in results.keys():
Like this:
total_A = []
for key in results.keys():
total_A.append(results[key]["A"])
print total_A
Result is
[10, 20]
In your case you could do
for key, value in results.items():
total_A.append(value["A"])
Then value will contain the value of the dictionary element, and you don't have to do the results[key] lookup explicitly.

If dict2 value = dict1 key, replace entire dict2 value with dict1 value

I have two dictionaries. In both dictionaries, the value of each key is a single list. If any element in any list in dictionary 2 is equal to a key of dictionary 1, I want to replace that element with the first element in that dictionary 1 list.
In other words, I have:
dict1 = {'IDa':['newA', 'x'], 'IDb':['newB', 'x']}
dict2 = {1:['IDa', 'IDb']}
and I want:
dict2 = {1:['newA', 'newB']}
I tried:
for ID1, news in dict1.items():
for x, ID2s in dict2.items():
for ID in ID2s:
if ID == ID1:
print ID1, 'match'
ID.replace(ID, news[0])
for k, v in dict2.items():
print k, v
and I got:
IDb match
IDa match
1 ['IDa', IDb']
So it looks like everything up to the replace method is working. Is there a way to make this work? To replace an entire string in a value-list with a string in another value-list?
Thanks a lot for your help.
Try this:
dict1 = {'IDa':['newA', 'x'], 'IDb':['newB', 'x']}
dict2 = {1:['IDa', 'IDb']}
for key in dict2.keys():
dict2[key] = [dict1[x][0] if x in dict1.keys() else x for x in dict2[key]]
print dict2
this will print:
{1: ['newA', 'newB']}
as required.
Explanation
dict.keys() gives us just the keys of a dictionary (i.e. just the left hand side of the colon). When we use for key in dict2.keys(), at present our only key is 1. If the dictionary was larger, it'd loop through all keys.
The following line uses a list comprehension - we know that dict2[key] gives us a list (the right side of the colon), so we loop through every element of the list (for x in dict2[key]) and return the first entry of the corresponding list in dict1 only if we can find the element in the keys of dict1 (dict1[x][0] if x in dict1.keys) and otherwise leave the element untouched ([else x]).
For example, if we changed our dictionaries to be the following:
dict1 = {'IDa':['newA', 'x'], 'IDb':['newB', 'x']}
dict2 = {1:['IDa', 'IDb'], 2:{'IDb', 'IDc'}}
we'd get the output:
{1: ['newA', 'newB'], 2: ['newB', 'IDc']}
because 'IDc' doesn't exist in the keys of dict1.
You could also use dictionary comprehensions, but I am not sure that they are working in Python 2.7, it may be limited to Python 3 :
# Python 3
dict2 = {k: [dict1.get(e, [e])[0] for e in v] for k,v in dict2.items()}
edit: I just checked, this is working in Python 2.7. However, dict2.items() should be replaced by dict2.iteritems() :
# Python 2.7
dict2 = {k: [dict1.get(e, [e])[0] for e in v] for k,v in dict2.iteritems()}
This was a fun one!
dict2[1] = [dict1[val][0] if val in dict1 else val for val in dict2[1]]
Or, here is the same logic without list comprehension:
new_dict = {1: []}
for val in dict2[1]:
if val in dict1:
new_dict[1].append(dict1[val][0])
else:
new_dict[1].append(val)
dict2 = new_dict

Python dictionary replace values

I have a dictionary with 20 000 plus entries with at the moment simply the unique word and the number of times the word was used in the source text (Dante's Divine Comedy in Italian).
I would like to work through all entries replacing the value with an actual definition as I find them. Is there a simple way to iterate through the keywords that have as a value a number in order to replace (as I research the meaning)?
The dictionary starts:
{'corse': 378, 'cielo,': 209, 'mute;': 16, 'torre,': 11, 'corsa': 53, 'assessin': 21, 'corso': 417, 'Tolomea': 21} # etc.
Sort of an application that will suggest a keyword to research and define.
via dict.update() function
In case you need a declarative solution, you can use dict.update() to change values in a dict.
Either like this:
my_dict.update({'key1': 'value1', 'key2': 'value2'})
or like this:
my_dict.update(key1='value1', key2='value2')
via dictionary unpacking
Since Python 3.5 you can also use dictionary unpacking for this:
my_dict = { **my_dict, 'key1': 'value1', 'key2': 'value2'}
Note: This creates a new dictionary.
via merge operator or update operator
Since Python 3.9 you can also use the merge operator on dictionaries:
my_dict = my_dict | {'key1': 'value1', 'key2': 'value2'}
Note: This creates a new dictionary.
Or you can use the update operator:
my_dict |= {'key1': 'value1', 'key2': 'value2'}
You cannot select on specific values (or types of values). You'd either make a reverse index (map numbers back to (lists of) keys) or you have to loop through all values every time.
If you are processing numbers in arbitrary order anyway, you may as well loop through all items:
for key, value in inputdict.items():
# do something with value
inputdict[key] = newvalue
otherwise I'd go with the reverse index:
from collections import defaultdict
reverse = defaultdict(list)
for key, value in inputdict.items():
reverse[value].append(key)
Now you can look up keys by value:
for key in reverse[value]:
inputdict[key] = newvalue
If you iterate over a dictionary you get the keys, so assuming your dictionary is in a variable called data and you have some function find_definition() which gets the definition, you can do something like the following:
for word in data:
data[word] = find_definition(word)
I think this may help you solve your issue.
Imagine you have a dictionary like this:
dic0 = {0:"CL1", 1:"CL2", 2:"CL3"}
And you want to change values by this one:
dic0to1 = {"CL1":"Unknown1", "CL2":"Unknown2", "CL3":"Unknown3"}
You can use code bellow to change values of dic0 properly respected to dic0to1 without worrying yourself about indexes in dictionary:
for x, y in dic0.items():
dic0[x] = dic0to1[y]
Now you have:
>>> dic0
{0: 'Unknown1', 1: 'Unknown2', 2: 'Unknown3'}
Just had to do something similar. My approach for sanitizing data for python based on Sadra Sabouri's answer:
def sanitize(value):
if str(value) == 'false':
return False
elif str(value) == 'true':
return True
elif str(value) == 'null':
return None
return value
for k,v in some_dict.items():
some_dict[k] = sanitize(v)
data = {key1: value1, key2: value2, key3: value3}
for key in data:
if key == key1:
data[key1] = change
print(data)
this will replace key1: value1 to key1: change

Merge 2 dictionaries in Python

I have 2 dictionaries.
dict1={('SAN RAMON', 'CA'): 1, ('UPLAND', 'CA'): 4, ('POUGHKEESIE', 'NY'): 3, ('CATTANOOGA', 'TN'): 1}
dict2={('UPLAND', 'CA'): 5223, ('PORT WASHING', 'WI'): 11174, ('PORT CLINTON', 'OH'): 6135, ('GRAIN VALLEY', 'MO'): 10352, ('GRAND JUNCTI', 'CO'): 49688, ('FAIRFIELD', 'IL'): 5165}
These are just samples, in reality each dict has hundreds of entries. I am trying to merge the two dictionaries and create dict 3 that contains {dict1.values(): dict2.values()} but only if that city appears in both dicts. So, one entry in dict3 would look like
{4:5223} # for 'UPLAND', 'CA' since it appears in both dict1 and dict2
This is just a small step in a larger function I am writing. I was going to try something like :
for item in dict1.keys():
if item not in dict2.keys():
del item
return dict[(dict1.keys())=(dict2.keys())]
I can't figure out how to make sure the number of complaints from dict1 matches the same city it is being referred to in dict2.
Here's what I think you want (demo):
dict3 = dict((dict1[key], dict2[key]) for key in dict1 if key in dict2)
Expanded a little, it looks like this:
dict3 = {}
for key in dict1:
if key in dict2:
dict3[dict1[key]] = dict2[key]
The common keys are:
set(dict1.keys()) & set(dict2.keys())
create dict 3 that contains {dict1.values(): dict2.values()}
This doesn't make sense, dictionaries are key-value pairs... what do you really want? Tip:
dict3 = {}
for k in set(dict1.keys()) & set(dict2.keys()):
dict3[dict1[k]]=dict2[k]
{4: 5223}
The straightforward way would be to check each key in one for membership in the other:
result = {}
for key in dict1:
if key in dict2:
result[dict1[key]] = dict2[key]
You could also try converting them into a set or frozenset and taking their intersection, but it's not clear to me whether that will be faster or not:
keys_in_both = frozenset(dict1) & frozenset(dict2)
result = dict((dict1[key], dict2[key]) for key in keys_in_both)

Categories

Resources