【问题标题】:Pythonic way to write nested for loopsPythonic 编写嵌套 for 循环的方法
【发布时间】:2020-07-18 19:07:25
【问题描述】:

我正在尝试按照用户代码中指定的顺序遍历多个动态生成的生成器。

我想修改run() 使其可以支持 n 个任务,而不是现在的三个。我尝试使用itertools.product(),但我不确定如何在我的发电机上一次调用next()

我想我必须在这里使用递归,但我不确定如何继续。任何积分都非常感谢。

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

我想要的输出是:

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

【问题讨论】:

  • 通常你用递归来做。我有几个关于“嵌套循环”的答案,但它们大多在 Common Lisp 或 Scheme 或 Prolog(或 Haskell)中。它也有一个完整的标签recursive-backtracking。然后在 C++ 中还有 thisthis
  • 这里是an answer,其中伪代码动态创建了 n 个嵌套循环。看看这些有什么帮助。

标签: python for-loop recursion nested


【解决方案1】:

这里是递归函数,其中 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)

【讨论】:

    【解决方案2】:

    如何修改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())
    

    这将确保调用所有n 数量的任务。

    【讨论】:

    • 每个任务都是嵌套循环的。这只会循环所有任务一次,不会产生所需的输出。
    • @pskeshu,现在已经编辑了我的答案。希望对你有帮助。
    猜你喜欢
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 2010-12-26
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多