Search code examples
pythonpython-3.xcsvblock

How can I reduce the line to avoid the "too many statically nested blocks"?


SyntaxError: too many statically nested blocks

I'm trying to parse the xml file to csv file. But I got this SyntaxError when for...in... condition is nested more than 20 times.

How can I reduce the line to avoid this SyntaxError?

for time in root.findall('A'):
    #print(time.text)
    row=[]
    row.append(time.text)
    for time in root.findall('B'):
        #print(time.text)
        row.append(time.text)
        for time in root.findall('C'):
            row.append(time.text)
            for time in root.findall('D'):
                row.append(time.text)
                for time in root.findall('E'):
                    row.append(time.text)
                    for time in root.findall('F'):
                        row.append(time.text)
                        for time in root.findall('G'):
                            row.append(time.text)
                            for time in root.findall('H'):
                                row.append(time.text)
                                for time in root.findall('I'):
                                    row.append(time.text)
                                    for time in root.findall('J'):
                                        row.append(time.text)
                                        for time in root.findall('K'):
                                            row.append(time.text)
                                            for time in root.findall('L'):
                                                row.append(time.text)
                                                for time in root.findall('M'):
                                                    row.append(time.text)
                                                    for time in root.findall('N'):
                                                        row.append(time.text)
                                                        for time in root.findall('O'):
                                                            row.append(time.text)
                                                            for time in root.findall('P'):
                                                                row.append(time.text)
                                                                for time in root.findall('Q'):
                                                                    row.append(time.text)
                                                                    for time in root.findall('R'):
                                                                        row.append(time.text)
                                                                        for time in root.findall('S'):
                                                                            row.append(time.text)
                                                                            for time in root.findall('T'):
                                                                                row.append(time.text)
for time in root.findall('U'):
                                                                                row.append(time.text)
    csvwriter.writerow(row)

Update Code

head = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    row = []
    for headstr in head:
        for value in root.findall(headstr):
            row.append(value.text)

Solution

  • Whatever you're trying to do, you're not doing it right. As written, with each loop indented further and further, this would append all the Bs for every A (so if there were 5 A entries and 3 B entries, you'd have A1, B1, B2, B3, A2, B1, B2, B3, A3, B1, B2, B3, A4, B1, B2, B3, A5, B1, B2, B3). And then all the Cs between every one of those entries, and so on. If the count of each type was even 2, you'd end up with over a million elements in your list; at three elements of each type, roughly 3.5 billion entries (enough to exhaust RAM on most home computers), and at four, over a trillion entries (enough to break most supercomputers).

    The only sane code I could imagine you intended wouldn't nest the loops at all; just dedent all the loops to the same indentation level, and ideally, make it just a doubly-nested loop, one over things to look for, one over the things found:

    row = []
    for tgt in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'):
        for time in root.findall(tgt):
            row.append(time.text)
    

    That gets all the unique elements of each type exactly once, with far less code, and no combinatoric explosion.

    The error you're getting is basically telling you "No reasonable code would ever do what you're doing, rethink your design."