【问题标题】:How can I reduce the line to avoid the "too many statically nested blocks"?如何减少行以避免“太多静态嵌套块”?
【发布时间】:2019-11-27 02:05:09
【问题描述】:

SyntaxError: 静态嵌套块过多

我正在尝试将 xml 文件解析为 csv 文件。 但是当for...in... 条件嵌套超过 20 次时,我得到了这个 SyntaxError。

如何减少行数以避免出现此 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)

更新代码

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)

【问题讨论】:

  • 为什么这些嵌套开始?
  • 您可以通过调用__next__使用生成器,每次都产生(返回)下一个元素

标签: python python-3.x csv block


【解决方案1】:

无论你想做什么,你都没有做对。如所写,随着每个循环的缩进越来越远,这将为 每个 A 附加 all Bs(所以如果有 5 个 A 条目和3 个B 条目,您将拥有A1, B1, B2, B3, A2, B1, B2, B3, A3, B1, B2, B3, A4, B1, B2, B3, A5, B1, B2, B3)。然后 all 在每个条目之间添加Cs,依此类推。如果每种类型的计数都是 2,那么您的 list 中将有超过一百万个元素;在每种类型的三个元素中,大约有 35 亿个条目(足以耗尽大多数家用计算机上的 RAM),在四个元素中,超过一万亿个条目(足以破坏大多数超级计算机)。

我能想象到你打算的唯一健全的代码根本不会嵌套循环;只需将所有循环缩进到相同的缩进级别,理想情况下,使其只是一个双重嵌套循环,一个在要查找的东西上,一个在找到的东西上:

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)

这将获得每种类型的所有唯一元素一次,代码少得多,并且没有组合爆炸。

您遇到的错误基本上是在告诉您“没有合理的代码可以完成您正在做的事情,请重新考虑您的设计。”

【讨论】:

  • @flakes:但这确实不可行。当然,您可以使用itertools.product 或类似方法将所有这些循环合并为一个,但它对 OP 的模式没有任何用处; OP的设计是荒谬的,“解决”他们提出的问题弊大于利。而且,不,即使作为生成器,OP 也没有任何意义;它会无缘无故地多次重复相同的输出,并且生成器的任何使用都将涉及与内存使用匹配的迭代;避免在宇宙热寂之前无法完成的代码耗尽内存是毫无意义的。
  • @flakes:简而言之,当 OP 拥有an XY problem 时,正确的答案不是修复他们损坏的 Y(他们无法解决的糟糕想法),而是解决 X (他们认为解决 Y 会有所帮助的问题,即使 Y 是处理问题 X 的糟糕方法)。
  • @ShadowRanger 感谢您的回复!您的建议是我应该修改以使其按我想要的方式工作的关键。
猜你喜欢
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多