[英]Dynamic Nested Loops - Generalization
Suppose I have the following 2 arbitrary classes:假设我有以下 2 个任意类:
class C1():
def __init__(self, a):
self.a = a
class C2():
def __init__(self, a):
self.a = a
And the following parameters:以及以下参数:
c1_args = [1, 2, 3, 4, 5]
c2_args = [1, 2, 3]
I want to run a function (let's call it do_something()
) n times, taking as arguments every possible pair of instances of (C1,C2) based on the parameters provided.我想运行一个函数(我们称之为
do_something()
)n 次,根据提供的参数将 (C1,C2) 的每个可能的实例对作为参数。 To do this, I created a nested loop, as shown below:为此,我创建了一个嵌套循环,如下所示:
for x in c1_args:
c1_instance = C1(x)
for y in c2_args:
c2_instance = C2(y)
do_something(c1_instance, c2_instance)
Now, I want to be able to generalize it for any number of classes (and parameters).现在,我希望能够将它概括为任意数量的类(和参数)。 For that, a simple - yet highly inefficient - way to do it would be to use
itertools.product()
, which I adapted from here :为此,一种简单但效率极低的方法是使用
itertools.product()
,我从这里改编:
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)
This is highly inefficient because it must create the same instance multiple times - in my example above, C1(1) must be created 3 times, once for every C2 instance created.这是非常低效的,因为它必须多次创建相同的实例——在我上面的例子中,C1(1) 必须创建 3 次,每个 C2 实例创建一次。 That's irrelevant with the simple classes I provided above but with bigger classes it is heavily time consuming.
这与我上面提供的简单类无关,但是对于更大的类,它非常耗时。
I suspect one solution would be recursion , based on what I found here .根据我在此处找到的内容,我怀疑一种解决方案是递归。 Unfortunately I can't seem to make it work for my case (mostly due to my ignorance on recursion - apologies for that)
不幸的是,我似乎无法让它适用于我的情况(主要是由于我对递归的无知 - 对此表示歉意)
If you create the instances first before looping throug the combinations, you can insure that the instances are only created once for each item in the lists:如果在遍历组合之前先创建实例,则可以确保为列表中的每个项目只创建一次实例:
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)
The prints show each __init__()
being called once and then the various combinations:打印显示每个
__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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.