Posts: 8
Threads: 2
Joined: Apr 2022
Hi,
Sorry for my bad english.
I need your help, please.
Something is wrong in my code and I don't understand what.
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = {}
for k1, v1 in r1.items():
for k2, v2 in r2.items():
if k1 != k2:
r.update({k1 : v1})
r.update({k2 : v2})
else:
r.update({k1 : v1 + v2})
r = {k : v for k,v in sorted(r.items())}
print(r) Output is :
Output: {'value 1': 13, 'value 2': 15, 'value 3': 1, 'value 4': 5, 'value 5': 12}
Why {"value 3" : 9} + {"value 3" : 1} isn't 10 ? Sum of 2 values ?
I would like to have this output :
Output: {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
How to do it ?
How to have a compact code ?
Thanks a lot.
Posts: 6,792
Threads: 20
Joined: Feb 2020
Apr-27-2022, 09:58 PM
(This post was last modified: Apr-29-2022, 01:06 PM by deanhystad.)
This is easier to see if we print something when k1 == k2 and also print r at the end of the outer loop.
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = {}
for k1, v1 in r1.items():
for k2, v2 in r2.items():
if k1 != k2:
r.update({k1 : v1})
r.update({k2 : v2})
else:
r.update({k1 : v1 + v2})
print("bang", k1, k2, r[k1])
print(k1, r) Output: value 1 {'value 1': 13, 'value 3': 1, 'value 5': 12}
value 2 {'value 1': 13, 'value 3': 1, 'value 5': 12, 'value 2': 15}
bang value 3 value 3 10
value 3 {'value 1': 13, 'value 3': 9, 'value 5': 12, 'value 2': 15}
value 4 {'value 1': 13, 'value 3': 1, 'value 5': 12, 'value 2': 15, 'value 4': 5}
Notice that even when k1 == k2, the sum value only remains there for a short time. The next time through the inner loop k2 == "value 5". k1 and k2 are no longer equal, so your code sets r[k1] = r1[k1] and r[k2] = r2[k2].
Maybe it would make sense to collect all the pairs and sum those.
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
items = list(r1.items()) + list(r2.items())
print(items) Output: [('value 1', 13), ('value 2', 15), ('value 3', 9), ('value 4', 5), ('value 3', 1), ('value 5', 12)]
Can you think of a way to add up the values for each of the keys when the data is presented this way?
Or maybe it is easier if you start with this:
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = r1.copy()
print(r) How would you add r2 values to r?
Posts: 1,583
Threads: 3
Joined: Mar 2020
Apr-27-2022, 11:14 PM
(This post was last modified: Apr-27-2022, 11:15 PM by bowlofred.)
Looks like a job for Counter()
from collections import Counter
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
c = Counter(r1)
c.update(r2)
print(c) Output: Counter({'value 2': 15, 'value 1': 13, 'value 5': 12, 'value 3': 10, 'value 4': 5})
Posts: 8
Threads: 2
Joined: Apr 2022
Apr-27-2022, 11:45 PM
(This post was last modified: Apr-27-2022, 11:45 PM by Bubu93200.)
(Apr-27-2022, 09:58 PM)deanhystad Wrote: This is easier to see if we print something when k1 == k1 and also print r at the end of the outer loop.
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = {}
for k1, v1 in r1.items():
for k2, v2 in r2.items():
if k1 != k2:
r.update({k1 : v1})
r.update({k2 : v2})
else:
r.update({k1 : v1 + v2})
print("bang", k1, k2, r[k1])
print(k1, r) Output: value 1 {'value 1': 13, 'value 3': 1, 'value 5': 12}
value 2 {'value 1': 13, 'value 3': 1, 'value 5': 12, 'value 2': 15}
bang value 3 value 3 10
value 3 {'value 1': 13, 'value 3': 9, 'value 5': 12, 'value 2': 15}
value 4 {'value 1': 13, 'value 3': 1, 'value 5': 12, 'value 2': 15, 'value 4': 5}
Notice that even when k1 == k2, the sum value only remains there for a short time. The next time through the inner loop k2 == "value 5". k1 and k2 are no longer equal, so your code sets r[k1] = r1[k1] and r[k2] = r2[k2].
Maybe it would make sense to collect all the pairs and sum those.
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
items = list(r1.items()) + list(r2.items())
print(items) Output: [('value 1', 13), ('value 2', 15), ('value 3', 9), ('value 4', 5), ('value 3', 1), ('value 5', 12)]
Can you think of a way to add up the values for each of the keys when the data is presented this way?
Or maybe it is easier if you start with this:
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = r1.copy()
print(r) How would you add r2 values to r?
ok.
My first code is too complex.
I found this one :
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = r1.copy()
for k2, v2 in r2.items():
if k2 in r.keys():
r[k2] = r[k2] + v2
else:
r.update({k2 : v2})
print(r) Output: {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
But always too complex.
Posts: 8
Threads: 2
Joined: Apr 2022
Apr-27-2022, 11:48 PM
(This post was last modified: Apr-27-2022, 11:48 PM by Bubu93200.)
(Apr-27-2022, 11:14 PM)bowlofred Wrote: Looks like a job for Counter()
from collections import Counter
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
c = Counter(r1)
c.update(r2)
print(c) Output: Counter({'value 2': 15, 'value 1': 13, 'value 5': 12, 'value 3': 10, 'value 4': 5})
Cool. Simple. I dont understand how it runs but it's very simple. It always runs with float values ?
Posts: 1,583
Threads: 3
Joined: Mar 2020
(Apr-27-2022, 11:48 PM)Bubu93200 Wrote: It always runs with float values ?
It just tries to _add_() the values.
If you don't give a value, it tries to add 1 .
If the key didn't exist before an update, it is initialized to 0 .
So technically you can add anything that supports addition (like strings), but it would be awkward and isn't intended to be used that way. I don't use it except as a simple (integer) counter.
Posts: 1,093
Threads: 143
Joined: Jul 2017
Apr-28-2022, 12:58 AM
(This post was last modified: Apr-28-2022, 12:59 AM by Pedroski55.)
There is a dictionary method dict.get(key, default = None)
That will be useful here:
Quote:>>> r2.get('value 1') == None
True
>>>
So you can check if the key is in the dictionary.
Also you need to somehow check that the contents can be added.
for key in r2.keys():
if r1.get(key) == None:
r1[key] = r2[key]
elif type(r1[key]) == type(r2[key]):
r1[key] = r1[key] + r2[key]
else:
r1[key] = 'Can not add the items, they are not the same type.'
for item in r1.items():
print(item) Quote:('value 1', 13)
('value 2', 15)
('value 3', 10)
('value 4', 5)
('value 6', 102)
('value 7', 'Can not add the items, they are not the same type.')
('value 8', 'cheese_sandwich')
('value 5', 12)
Posts: 6,792
Threads: 20
Joined: Feb 2020
Apr-28-2022, 06:45 AM
(This post was last modified: Apr-28-2022, 06:45 AM by deanhystad.)
from collections import Counter
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = dict(sorted((Counter(r1) + Counter(r2)).most_common()))
print("Counter", r)
r = r1.copy()
for key, value in r2.items():
r[key] = r.get(key, 0) + value
r = dict(sorted(r.items()))
print("Loop", r) Output: Counter {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
Loop {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
Posts: 8
Threads: 2
Joined: Apr 2022
Apr-28-2022, 10:53 PM
(This post was last modified: Apr-28-2022, 10:53 PM by Bubu93200.)
(Apr-28-2022, 06:45 AM)deanhystad Wrote: from collections import Counter
r1 = {'value 1': 13, 'value 2': 15, 'value 3': 9, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r = dict(sorted((Counter(r1) + Counter(r2)).most_common()))
print("Counter", r)
r = r1.copy()
for key, value in r2.items():
r[key] = r.get(key, 0) + value
r = dict(sorted(r.items()))
print("Loop", r) Output: Counter {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
Loop {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
Thanks a lot all.
I changed r1 to have a non sorted dictionary (I want a sorted dictionary as output)
So my solution with dictionary comprehension (inspired by deanhystad !  ) :
r1 = {'value 1': 13, 'value 3': 9, 'value 2': 15, 'value 4': 5}
r2 = {'value 3': 1, 'value 5': 12}
r =r1.copy()
r.update({key : r.get(key, 0) + value for key, value in sorted(r2.items())})
r = dict(sorted(r.items())) #just a sorted dictionary
print(r) Output: {'value 1': 13, 'value 2': 15, 'value 3': 10, 'value 4': 5, 'value 5': 12}
2 lines if I want a sorted dictionary but not necessary. 1 line if not.... GREAT ! thks all !
|