使用共享变量重构嵌套循环



我有一个函数,它使用嵌套循环处理一些非常嵌套的数据。它的简化结构是这样的:

def process_elements(root):
for a in root.elements:
if a.some_condition:
continue
for b in a.elements:
if b.some_condition:
continue
for c in b.elements:
if c.some_condition:
continue
for d in c.elements:
if d.some_condition:
do_something_using_all(a, b, c, d)

这对我来说并不是很像蟒蛇,所以我想重构它

def process_elements(root):
for a in root.elements:
if a.some_condition:
continue
process_a_elements(a)

def process_a_elements(a):
for b in a.elements:
if b.some_condition:
continue
process_b_elements(b)

def process_b_elements(b):
for c in b.elements:
if c.some_condition:
continue
process_c_elements(c)

def proccess_c_elements(c):
for d in c.elements:
if d.some_condition:
do_something_using_all(a, b, c, d) # Problem: I do not have a nor b!

正如你所看到的,对于更嵌套的级别,我需要使用它的所有";"父";元素。函数将具有唯一的作用域,因此我无法访问这些元素。将前面的所有元素传递给每个函数(如proccess_c_elements(c, a, b)(看起来确实很难看,对我来说也不太像蟒蛇。。。

有什么想法吗?

我不知道代码的确切数据结构和复杂性,但您可以尝试使用列表将对象引用传递给下一个菊花链函数,如下所示:

def process_elements(root):
for a in root.elements:
if a.some_condition:
continue
listobjects=[]
listobjects.append(a)
process_a_elements(a,listobjects)

def process_a_elements(a,listobjects):
for b in a.elements:
if b.some_condition:
continue
listobjects.append(b)
process_b_elements(b,listobjects)
def process_b_elements(b,listobjects):
for c in b.elements:
if c.some_condition:
continue
listobjects.append(c)
process_c_elements(c,listobjects)

def process_c_elements(c,listobjects):
for d in c.elements:
if d.some_condition:
listobjects.append(d)
do_something_using_all(listobjects)
def do_something_using_all(listobjects):
print(listobjects)

FWIW,我找到了一个解决方案,它将所有处理封装在一个类中,并具有跟踪当前处理的元素的属性:

class ElementsProcessor:
def __init__(self, root):
self.root = root

self.currently_processed_a = None
self.currently_processed_b = None

def process_elements(self):
for a in self.root.elements:
if a.some_condition:
continue
self.process_a_elements(a)

def process_a_elements(self, a):
self.currently_processed_a = a
for b in a.elements:
if b.some_condition:
continue
self.process_b_elements(b)

def process_b_elements(self, b):
self.currently_processed_b = b
for c in b.elements:
if c.some_condition:
continue
self.process_c_elements(c)

def process_c_elements(self, c):
for d in c.elements:
if d.some_condition:
do_something_using_all(
self.currently_processed_a,
self.currently_processed_b,
c,
d
)

最新更新