Reputation: 1546
There must be a question about this, but I can't find.
I have a dictionary like this:
data = {
"Jan": {
"2017-01-01 00:00:00": {
"001": 10,
"002": 20,
"003": 30
},
"2017-01-01 01:00:00": {
"001": 20,
"002": 40,
"003": 50
},
"2017-01-01 02:00:00": {
"001": 90,
"002": 50,
"003": 60
}
}
}
I want to loop through the dictionary and calculate the cumulative point, altering the dictionary if possible. For example, for 001
it would be
data["Jan"]["2017-01-01 00:00:00"]["001"] == 10
data["Jan"]["2017-01-01 01:00:00"]["001"] == 30
data["Jan"]["2017-01-01 02:00:00"]["001"] == 120
I don't want to get the final cumulative sum, I want the relative.
Right now I have this code:
import copy
from datetime import datetime, timedelta
copydata = copy.deepcopy(data)
# I made a copy because I have an if statement and Python was
complaining that the dictionary changed size during iteration
for i, month in enumerate(copydata):
for dt in copydata[month]:
for user in copydata[month][dt]:
current_datetime = datetime.strptime(dt, '%Y-%m-%d %H:00:00')
cumulativepoints=data[month][dt][user] # getting the current hour's points. Since the loop is in random order, it can start at any time
if current_datetime.hour > 0: # if the hour is 0 then it's the first hour and I don't need to calculate anything
for x in range(1, current_datetime.hour+1): # starting at 01:00:00 till the current_datetime.hour plus one to count itself
past_time = current_datetime - timedelta(hours=x)
past_time = past_time.strftime('%Y-%m-%d %H:00:00')
if data[month][past_time]:
cumulativepoints += data[month][past_time][user]
data[month][past_time][user] = cumulativepoints # <--- the error happens here
But at that line data[month][past_time][user] = cumulativepoints
, Python throws an error: TypeError: list indices must be integers, not str
I'm pretty sure this code is a lot more complicated than it should be. But that is the result of many adaptations due to many error messages.
Upvotes: 0
Views: 837
Reputation: 15533
Question: Loop through multidimensional dictionary and calculate
You can do it, for instance:
def pp_dict():
for month in data:
print('month:{}'.format(month))
for dt in sorted(data[month]):
print('\tdt:{}'.format(dt))
for user in sorted(data[month][dt]):
print('\t\tuser:{}:{}'.format(user, data[month][dt][user]))
def cum_sum(month, user):
cum_sum = 0
for dt in sorted(data[month]):
cum_sum += data[month][dt][user]
data[month][dt][user] = cum_sum
for user in ['001']:
cum_sum('Jan', user)
pp_dict()
Output:
month:Jan dt:2017-01-01 00:00:00 user:001:10 user:002:20 user:003:30 dt:2017-01-01 01:00:00 user:001:30 user:002:40 user:003:50 dt:2017-01-01 02:00:00 user:001:120 user:002:50 user:003:60
Tested with Python: 3.4.2
Upvotes: 1