2016-01-14 162 views
2

進行遍歷時,我有我通過以試圖循環寫入Excel文件嵌套的字典。的Python:冗餘通過嵌套字典

這是發起並創建嵌套的字典

def tree(): return defaultdict(tree) 
KMstruct = tree() 
for system in sheet.columns[0]: 
if system.value not in KMstruct: 
    KMstruct[system.value] 
    for row in range(1,sheet.get_highest_row()+1): 
     if sheet['A'+str(row)].value == system.value and sheet['B'+str(row)].value not in KMstruct: 
      KMstruct[system.value][sheet['B'+str(row)].value] 
      if sheet['B'+str(row)].value == sheet['B'+str(row)].value and sheet['C'+str(row)].value not in KMstruct: 
       KMstruct[system.value][sheet['B'+str(row)].value][sheet['C'+str(row)].value] 
       if sheet['C'+str(row)].value == sheet['C'+str(row)].value and sheet['D'+str(row)].value not in KMstruct: 
        KMstruct[system.value][sheet['B'+str(row)].value][sheet['C'+str(row)].value][sheet['D'+str(row)].value] 
        KMstruct[system.value][sheet['B'+str(row)].value][sheet['C'+str(row)].value][sheet['D'+str(row)].value] = [sheet['E'+str(row)].value] 

這是代碼的代碼,我遍歷它:

for key in KMstruct.keys(): 
r += 1 
worksheet.write(r, col,  key) 
for subkey in KMstruct[key]: 
    if currsubkeyval != subkey: 
     r += 1 
     worksheet.write(r, col,  key) 
    r +=1 
    worksheet.write(r, col, key + '\\' + subkey) 
    for item in KMstruct[key][subkey]: 
     if curritemval != item: 
      r +=1 
      worksheet.write(r, col, key + '\\' + subkey) 
     for subitem in KMstruct[key][subkey][item]: 
      r += 1 
      worksheet.write(r, col, key + '\\' + subkey + '\\' + item) 
      worksheet.write(r, col + 1, subitem) 
      curritemval = item 
      for finalitem in KMstruct[key][subkey][item][subitem]: 
       r += 1 
       worksheet.write(r, col, key + '\\' + subkey + '\\' + item + '\\' + subitem) 
       worksheet.write(r, col + 1, KMstruct[key][subkey][item][subitem]) 

熊與我這個代碼,因爲我是一個小白,我知道這不是很美麗。無論如何,我的問題是最後一個循環。我正在嘗試使用KMstruct[key][subkey][item][subitem]中的字符串值,但循環變量lastitem需要檢查每個字符串的字符串值(注意:密鑰subitem包含字符串列表)。這意味着,如果我只有一個要寫入的值,它會被寫入字符串中有字符的次數。

例如: - 價值:蘋果將在一個新的Excel行被寫入5倍

什麼我錯在這裏做什麼?

編輯:冗餘問題已經解決,但現在我需要了解在將我的最後一項,即我的字符串列表分配給子項鍵時,如果我做錯了什麼。

回答

0

問題是,在Python中,str也是可迭代的,例如:

>>> for s in 'hello': 
... print(s) 

h 
e 
l 
l 
o 

所以您可能需要避免迭代當該值是一個str,或者包裹在另一迭代的str(例如一個list),以便它可以以相同的方式處理。這是由你如何構建你的代碼有點困難。例如,以下內容:

for key in KMstruct.keys(): 
    for subkey in KMstruct[key]: 

...可以寫爲:

for key, value in KMstruct.items(): 
    for subkey, subvalue in value.items(): 

...給你在每次循環,使它可以應用測試。

for key, val in KMstruct.items(): 
r += 1 
worksheet.write(r, col,  key) 

for subkey, subval in val.items(): 
    if currsubkeyval != subkey: 
     r += 1 
     worksheet.write(r, col,  key) 
    r +=1 
    worksheet.write(r, col, key + '\\' + subkey) 

    for item, itemval in subval.items(): 
     if curritemval != item: 
      r +=1 
      worksheet.write(r, col, key + '\\' + subkey) 

     for subitem, subitemval in itemval.items(): 
      r += 1 
      worksheet.write(r, col, key + '\\' + subkey + '\\' + item) 
      worksheet.write(r, col + 1, subitem) 
      curritemval = item 

      # I am assuming at this point subitemval is either a list or a str? 
      if type(subitemval) == str: 
       # If it is, wrap it as a list, so the next block works as expected 
       subitemval = [subitemval] 

      for finalitem in subitemval: 
       r += 1 
       worksheet.write(r, col, key + '\\' + subkey + '\\' + item + '\\' + subitem) 
       worksheet.write(r, col + 1, finalitem) # This should be finalitem, correct? 

這裏我們測試subitemval的類型,如果它是一個str包裝在一個列表[str]所以下面塊迭代預期。在最後一行沒有輸出finalitem也有一個明顯的錯誤。如果沒有您的示例數據進行測試是不可能的,但它應該在功能上等同。

+0

這完美地工作,非常感謝!關於subitemval是列表還是str的問題,答案是subitemval應該是str的列表。所以我想要實現的是寫出所有子項目,即各個子項目的最終項目。你知道我可以怎麼做嗎? – Sajruss

+0

上面的代碼應該做到這一點!類型檢查應確保「subitemval」總是一個列表,所以「對於subitemval中的finalitem」將正確地迭代它。 – mfitzp

+0

不幸的是,目前情況並非如此,它只打印出第一個子項目。我懷疑我在構建詞典和分配子項時犯了錯誤。你介意看那部分嗎? – Sajruss

0

你眼前的問題是,你的榜樣的最後一行應該是:

   worksheet.write(r,col+1, finalitem) 

順便說一句,你的代碼將是一個更容易閱讀,如果你創建了偶爾的臨時變量,如:

 subitemlist = KMstruct[key][subkey][item] 
     for subitem in subitemlist: