2017-06-14 76 views
0

必須有一個關於這個問題,但我找不到。循環通過多維詞典並計算

我有這樣的詞典:通過字典

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 
     } 
    } 
} 

我想環路和計算累積點,改變字典如果可能的話。例如,對於001這將是

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 

我不想得到最終的累計總和,我想相對。

現在我有這樣的代碼:

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 

但在該行data[month][past_time][user] = cumulativepoints,Python中拋出一個錯誤:TypeError: list indices must be integers, not str

我敢肯定,這個代碼是一個複雜得多比它應該是。但這是由於許多錯誤信息導致許多改編的結果。

+0

了'dict'不會是一個很好的數據結構爲此,它不是有序的,並且您將按隨機順序迭代密鑰。但是順序對於你想要完成的任務是至關重要的...... –

+0

@rlcabral,我在Python 2.7.3中沒有收到任何錯誤。假設存在問題,請嘗試在「int()」函數中封裝變量'cumulativepoints'。同樣用'data [month] [past_time] [user]'對上面的行做同樣的事情。我感覺你不小心傳遞了一個字符串而不是一個整數。 – SirJames

+0

@SirJames,同樣的錯誤 – rlcabral

回答

1

Question: Loop through multidimensional dictionary and calculate

你可以做到這一點,例如:

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 

測試使用Python 3.4.2

+0

您的方法存在的問題是它會針對單個用戶進行計算。我需要遍歷所有調用每個用戶函數的數據,並且它肯定會多次調用具有相同參數的函數。但現在,我想說你的答案將不得不爲我工作。 – rlcabral

+0

@rlcabral:在['001']:'中爲用戶添加儘可能多的用戶,例如'['001','002']中的用戶':等等。 – stovfl