【问题标题】:Dynamic Nested Loops - Generalization动态嵌套循环 - 泛化
【发布时间】:2021-01-15 05:03:36
【问题描述】:

假设我有以下 2 个任意类:

class C1():
    def __init__(self, a):
        self.a = a
class C2():
    def __init__(self, a):
        self.a = a

还有以下参数:

c1_args = [1, 2, 3, 4, 5]
c2_args = [1, 2, 3]

我想运行一个函数(我们称它为do_something())n 次,根据提供的参数将每个可能的 (C1,C2) 实例对作为参数。为此,我创建了一个嵌套循环,如下所示:

for x in c1_args:
    c1_instance = C1(x)
    for y in c2_args:
        c2_instance = C2(y)
        do_something(c1_instance, c2_instance)

现在,我希望能够将它推广到任意数量的类(和参数)。为此,一种简单但效率极低的方法是使用itertools.product(),我改编自here

import itertools
def generalize(classes, args):
    combos = itertools.product(*args)
    for combo in combos:
        instances = [classes[i](args[i]) for i in range(len(combo))]
        do_something(instances)

这是非常低效,因为它必须多次创建同一个实例 - 在我上面的示例中,C1(1) 必须创建 3 次,每个 C2 实例创建一次。这与我上面提供的简单类无关,但是对于更大的类,它非常耗时。

根据我发现的here,我怀疑一种解决方案是递归。不幸的是,我似乎无法让它适用于我的情况(主要是由于我对递归的无知 - 对此表示歉意)

【问题讨论】:

  • 递归如何使您免于创建新的类实例?
  • 这听起来更像是一个设计问题
  • 我怀疑递归可能允许我根据我链接的 Anti Earth 的问题动态创建嵌套循环 - 但老实说我对递归的概念不太熟悉 @inspectorG4dget

标签: python loops for-loop recursion nested


【解决方案1】:

如果在循环遍历组合之前先创建实例,则可以确保为列表中的每个项目只创建一次实例:

from itertools import product

class C1():
    def __init__(self, a):
        print("making c1:", a)
        self.a = a
    def __repr__(self):
        return f"C1({self.a})"

class C2():
    def __init__(self, a):
        print("making c2:", a)
        self.a = a
        
    def __repr__(self):
        return f"C2({self.a})"

c1_args = map(C1, [1, 2, 3, 4, 5])
c2_args = map(C2, [1, 2, 3])


for comb in product(c1_args, c2_args):
    print(comb)

打印显示每个 __init__() 被调用一次,然后是各种组合:

making c1: 1
making c1: 2
making c1: 3
making c1: 4
making c1: 5
making c2: 1
making c2: 2
making c2: 3
(C1(1), C2(1))
(C1(1), C2(2))
(C1(1), C2(3))
(C1(2), C2(1))
(C1(2), C2(2))
(C1(2), C2(3))
(C1(3), C2(1))
(C1(3), C2(2))
(C1(3), C2(3))
(C1(4), C2(1))
(C1(4), C2(2))
(C1(4), C2(3))
(C1(5), C2(1))
(C1(5), C2(2))
(C1(5), C2(3))

【讨论】:

    猜你喜欢
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多