简体   繁体   English

Python:遍历嵌套字典时的冗余

[英]Python: Redundancy when iterating through nested dictionary

I have a nested dictionary which I am trying to loop through in order to write to an excel file. 我有一个嵌套的字典,正在尝试遍历以便写入excel文件。

This is the code which initiates and creates the nested dictionary 这是启动和创建嵌套字典的代码

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]

This is the code where I loop through it: 这是我遍历的代码:

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

Bear with me on this code since I am a noob, I am aware that this is not so beautiful. 因为我是菜鸟,所以请耐心等待这段代码,我知道这不是那么漂亮。 Anyhow, my problem is the last loop. 无论如何,我的问题是最后一个循环。 I am trying to take the string values in KMstruct[key][subkey][item][subitem] but the loop variable lastitem goes through each char of key's string value (note: the key subitem contains a list of strings). 我试图把在字符串值KMstruct[key][subkey][item][subitem]但循环变量lastitem经过键的字符串值中的每个字符(注:关键subitem包含字符串列表)。 This means that if I only have one value that is to be written, it gets written as many times as there are characters in the string. 这意味着,如果我只有一个要写入的值,则该值将被写入与字符串中的字符一样多的次数。

Eg: value: apple will be written on a new excel row 5 times 例如:值:苹果将在新的Excel行中写入5次

What am I doing wrong here? 我在这里做错了什么?

Edit: The issue on the redundancy has been solved but now I need to understand if I am doing something wrong when assigning my lastitem, ie my list of strings, to the subitem key. 编辑:关于冗余的问题已经解决,但现在我需要了解在将我的lastite(即我的字符串列表)分配给subitem键时是否做错了什么。

Your immediate problem is that the last line of your example should be: 您的直接问题是示例的最后一行应为:

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

BTW, your code would be a lot easier to read if you created occasional temporary variables like: 顺便说一句,如果您创建了以下临时临时变量,则代码将更容易阅读:

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

The problem is that in Python a str is also an iterable, for example: 问题在于,在Python中, str也是可迭代的,例如:

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

h
e
l
l
o

So you either need to avoid iterating when the value is a str , or wrap the str in another iterable (eg a list ) so that it can be handled the same way. 因此,您要么需要避免在值是str时进行迭代,要么将str包裹在另一个可迭代项(例如list )中,以便可以用相同的方式进行处理。 This is made slightly difficult by how you are structuring your code. 通过如何构造代码,这变得有些困难。 For example, the following: 例如,以下内容:

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

...can be written as: ...可以写成:

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

...giving you the value on each loop, making it possible to apply a test. ...在每个循环中为您提供 ,从而可以进行测试。

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?

Here we test the type of the subitemval and if it is a str wrap it in a list [str] so the following block iterates as expected. 在这里,我们测试subitemval的类型,如果它是str ,则将其包装在列表[str]以便以下块按预期进行迭代。 There is also an apparent bug where you are not outputting the finalitem on the last line. 还有一个明显的错误,即您没有在最后一行输出finalitem It's not posssible to test this without your example data but it should be functionally equivalent. 没有示例数据就无法对此进行测试,但是在功能上应该等效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM