Python:通过嵌套字典迭代时的冗余

我有一个嵌套字典,我试图通过循环来写入一个Excel文件。

这是启动并创build嵌套字典的代码

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]) 

因为我是一个noob,忍受这个代码,我知道这不是很美丽。 无论如何,我的问题是最后一个循环。 我试图在KMstruct[key][subkey][item][subitem]KMstruct[key][subkey][item][subitem]string值,但循环variableslastitem遍历每个string的string值(注意:该子键包含一个string列表)。 这意味着,如果我只有一个要写入的值,它会被写入string中有字符的次数。

例如:value:苹果将被写入一个新的excel行5次

我在这里做错了什么?

编辑:冗余的问题已经解决,但现在我需要了解,如果我把我的最后一项,即我的string列表分配给子项目时,做错了什么。

问题是,在Python中, str也是可迭代的,例如:

 >>> for s in 'hello': ... print(s) h e l l o 

所以当你的值是一个str ,你要么避免迭代,要么将str包装在另一个迭代器(例如一个list )中,以便可以用同样的方式处理。 这是由你如何构build你的代码有点困难。 例如,以下内容:

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

…可以写成:

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

…给你每个循环的价值 ,使其可以申请一个testing。

 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? 

在这里,我们testingsubitemval的types,如果它是一个str包装它在列表[str]所以下面的块按预期迭代。 还有一个明显的错误,你没有输出最后一行的最后一项。 如果没有您的示例数据进行testing,这是不可能的,但它应该在function上是等同的。

你直接的问题是你的例子的最后一行应该是:

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

顺便说一句,如果你创build了偶尔的临时variables,你的代码会更容易阅读:

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