简体   繁体   English

Pythonic 编写嵌套 for 循环的方法

[英]Pythonic way to write nested for loops

I'm trying to iterate through multiple generators that are dynamically generated, in the order as specified in the user code.我正在尝试按照用户代码中指定的顺序遍历多个动态生成的生成器。

I want to modify run() so that it can support n number of tasks, as opposed to three as of now.我想修改run()以便它可以支持 n 个任务,而不是现在的三个。 I tried using itertools.product() but I'm not sure how to call next() on my generators one at a time.我尝试使用itertools.product()但我不确定如何一次在我的生成器上调用next()

I think I will have to use recursion here but I'm not sure how to proceed.我想我将不得不在这里使用递归,但我不确定如何继续。 Any points are greatly appreciated.任何点都非常感谢。

class ImageSeries:
    def __init__(self):
        self.tasks = []

    def xy(self, position):
        print(f"xy: {position}")
        yield "xy"

    def z(self, position):
        print(f"z: {position}")
        yield "z"

    def exp(self, exposure):
        print(f"exp: {exposure}")
        yield "exposure"

    def xy_scan(self, positions):
        self._xy_task = lambda: (self.xy(pos) for pos in positions)
        self.tasks.append(self._xy_task)
    
    def z_scan(self, positions):
        self._z_task = lambda: (self.z(pos) for pos in positions)
        self.tasks.append(self._z_task)

    def exp_scan(self, exposures):
        self._exp_task = lambda: (self.exp(e) for e in exposures)
        self.tasks.append(self._exp_task)

    def run(self):
        for generator_0 in self.tasks[0]():
            next(generator_0)
            for generator_1 in self.tasks[1]():
                next(generator_1)
                for generator_2 in self.tasks[2]():
                    next(generator_2)

    def __repr__(self):
        return str(self.self.tasks)


if __name__ == "__main__":
    s = ImageSeries()
    positions = [[0, 0], [100, 100], [1000, 1000]]
    s.xy_scan(positions)
    s.exp_scan([50, 100, 150])
    s.z_scan([0, 100, 1000, 10000])
    s.run()

My desired output is:我想要的 output 是:

xy: [0, 0]
exp: 50
z: 0
z: 100
z: 1000
z: 10000
exp: 100
z: 0
z: 100
z: 1000
z: 10000
exp: 150
z: 0
z: 100
z: 1000
z: 10000
xy: [100, 100]
exp: 50
z: 0
z: 100
z: 1000
z: 10000
exp: 100
z: 0
z: 100
z: 1000
z: 10000
exp: 150
z: 0
z: 100
z: 1000
z: 10000
xy: [1000, 1000]
exp: 50
z: 0
z: 100
z: 1000
z: 10000
exp: 100
z: 0
z: 100
z: 1000
z: 10000
exp: 150
z: 0
z: 100
z: 1000
z: 10000

How about modifying the for loop in run method as below,如何在run方法中修改for循环,如下所示,

def get_task(self):
    for task in self.tasks:
        yield task()

def loop_over(self, generator_obj):
    for generator in generator_obj:
        next(generator)
    self.loop_over(self.get_task())    

def run(self):
    self.loop_over(self.get_task())

This will ensure that all the n number of tasks are called.这将确保调用所有n个任务。

Here is the recursive function where n should be start with 0这是递归 function ,其中 n 应以 0 开头

def run(self,n):
    for generator in self.tasks[n]():
        next(generator)
        m=n+1
        if m < len(self.tasks):
            self.run(m)

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

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