Python Forum
what is wrong. Why python doesn't ad my values ?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
what is wrong. Why python doesn't ad my values ?
#1
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.
Reply
#2
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?
Reply
#3
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})
Reply
#4
(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.
Reply
#5
(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 ?
Reply
#6
(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.
Reply
#7
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)
Reply
#8
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}
Reply
#9
(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 ! Smile Smile ) :
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 ! Smile Tongue
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Why doesn't this code work? What is wrong with path? Melcu54 7 1,804 Jan-29-2023, 06:24 PM
Last Post: Melcu54
  Am I wrong or is Udemy wrong? String Slicing! Mavoz 3 2,572 Nov-05-2022, 11:33 AM
Last Post: Mavoz
  why doesn't python look in two directions Kakha 21 6,501 Jan-01-2021, 11:24 PM
Last Post: jefsummers
  Python IDE doesn't see opencv-python package on my Jetson Nano sadhaonnisa 1 3,351 Oct-11-2020, 01:04 AM
Last Post: Larz60+
  python gives wrong string length and wrong character thienson30 2 3,013 Oct-15-2019, 08:54 PM
Last Post: Gribouillis
  Python: command “python -m pip install --upgrade pip” doesn't work apollo 2 13,319 Sep-16-2019, 03:11 PM
Last Post: snippsat
  wrong values cybervulcan 3 2,916 Jun-17-2018, 08:32 PM
Last Post: cybervulcan

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020