Reputation: 83
I'm trying to continously add a value to a dictionary's key's value, to form a sum of an old and new value.
My code checks if one string [str_1] from now is the same as a string from 1 second ago, [str_2] if it isn't, it should create a key with the key from 1 second ago, store for how long it's been on that string and move on to the next [str_?], repeating the process for a new string (creating a new key), then, if it meets any of the strings stored [str_?], it should take that key's value and add the new value on top of it, to create a sum.
seconds = 0
my_dict = {}
stop = 0
while stop != 1:
then_string = getStringValue() #Copies a string from somewhere.
sleep(1)
now_string = getStringValue() #Copies a string from somewhere, note, we waited 1 sec.
if then_string == now_string:
seconds += 1
elif then_string != now_string:
my_dict[then_string] = seconds
"""This is where I'm stuck."""
seconds = 0 #Resets the seconds.
else:
pass
My problem is that once I get to the elif (strings changed, alarm for adding new value), it breaks.
It only adds the value of seconds, even if I were to do something like
my_dict[then_string] = my_dict.get(then_string) + seconds
The value is a seemingly doubled number of seconds and it yields improper results.
My goal is to properly get the seconds spent on a string.
Upvotes: 1
Views: 346
Reputation: 1738
Dictionary Approach
Going down the dictionary method as per the original post, this would be how I would tackle it. Note the try
/except
- in place addition will throw a KeyError
if the key doesn't yet exist.
seconds = 0
my_dict = {}
stop = 0
while stop != 1:
then_string = getStringValue() #Copies a string from somewhere.
sleep(1)
now_string = getStringValue() #Copies a string from somewhere, note, we waited 1 sec.
if then_string == now_string:
seconds += 1
elif then_string != now_string:
try:
# let's assume the key exists
my_dict[then_string] += seconds
except KeyError:
# oh no! it doens't exist, let's set it at seconds
my_dict[then_string] = seconds
seconds = 0 #Resets the seconds.
else:
pass
Collections Approach
However, python has a special container type for just this task called collections.Counter()
, which is an extended dictionary.
from collections import Counter
seconds = 0
my_counter = Counter()
stop = 0
while stop != 1:
sv = getStringValue()
c.update(sv = 1)
sleep(1)
# do something here to ascertain when to set stop = 1
else:
del sv
# output a nice count of all sv's and the second count
print(c)
Upvotes: 0
Reputation: 2996
Check if key then_string
exists in my_dict
:
Use in
to check existence.
if then_string in my_dict:
my_dict[then_string] += second
else:
my_dict[then_string] = second
Use dict.get(key, default_value)
to get value or default value if key doesn't exist.
my_dict[then_string] = my_dict.get(then_string, 0) + second
Use defaultdict
from collection
. Reference
from collections import defaultdict
my_dict = defaultdict(int) # Set default to an int, or 0
my_dict[then_string] += second
The entire code will become
seconds = 0
my_dict = {}
stop = 0
while stop != 1:
then_string = getStringValue()
sleep(1)
now_string = getStringValue()
if then_string == now_string:
seconds += 1
elif then_string != now_string:
# Modify here.
if then_string in my_dict:
my_dict[then_string] += second
else:
my_dict[then_string] = second
seconds = 0
else:
pass
Upvotes: 2
Reputation: 449
You could use a while loop, which I think is a bit more logical.
then_string = getStringValue()
now_string = then_string
while stop != 1:
seconds = 0
while then_string==now_string:
time.sleep(1)
seconds += 1
now_string = getStringValue()
if then_string in my_dict:
my_dict[then_string] += seconds
else:
my_dict[then_string] = seconds
then_string = now_string
Upvotes: 0
Reputation: 4332
I would utilize pythons object powers. Maybe consider code like this which is a lot simpler.
# Extend dict with a new increment method.
class increment_dict(dict):
def increment(self, key):
# increment increases key by one.
# self.get(key,0) will return 0 if key not in self.
self[key] = self.get(key, 0) + 1
running = True
i_dict = increment_dict()
# I dont need to remember what I saw last just increase the count of
# seconds by on every time I see a string. Both are constant runtime
# and without string equality this I suspect will be faster.
while running:
sleep(1)
i_dict.increment(getStringValue())
Upvotes: 1