2016-01-14 102 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: