【问题标题】:Function with varying number of for loops using the arguments in the loop使用循环中的参数具有不同数量的 for 循环的函数
【发布时间】:2020-02-14 09:22:33
【问题描述】:

首先我想说我已经阅读了这个帖子:

Function with varying number of For Loops (python)

虽然它看起来确实与我想知道的相似,但我(根本)不够精通递归以使其工作。

如果我有以下sn-p:

I = ["i" + str(i+1) for i in range(3)]
J = ["j" + str(i+1) for i in range(4)]
K = ["k" + str(i+1) for i in range(2)]

然后我可以做一个这样的函数:

def f(*Sets):
    size = len(Sets)
    if size == 1:
        for i in Sets[0]:
            print(i)
    elif size == 2:
        for i in Sets[0]:
            for j in Sets[1]:
                print(i,j)
    elif size == 3:
        for i in Sets[0]:
            for j in Sets[1]:
                for k in Sets[2]:
                    print(i,j,k)

当执行时,它会产生类似的东西:

>>f(I)
i1
i2
i3

>>f(I,J)
i1,j1
i1,j2
...
i3,j4

>>f(I,J,K)
i1,j1,k1
i1,j1,k2
...
i3,j4,k2

print 语句只是一个示例。我想在检查循环变量或字典的同时实际访问熊猫数据框中的元素,因此它将包含一些命令,如print(i,j,k, ":", dictionary[i,j,k])。我需要访问循环中的每个变量,这就是我的意思。

在我看来,这可以通过某种递归来广泛减少。因为例如,如果我需要四个列表,我必须添加另一个 elif。但是我没有递归式的思维,也看不出怎么解决。

或者可能根本无法完成。什么都不知道了:P

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    您可以使用递归来实现这一点,但最简单的方法是使用itertools.product

    from itertools import product
    
    def f(*sets):
        for p in product(*sets):
            # e.g. (1, 3, 5)
            print(*p)
    
    >>> f([1, 2], [3, 4], [5, 6])
    1 3 5
    1 3 6
    1 4 5
    1 4 6
    2 3 5
    2 3 6
    2 4 5
    2 4 6
    

    producttuples 上以惰性迭代器的形式返回输入迭代的笛卡尔积。

    笛卡尔积的简单递归实现将遵循以下几行:

    def f(*sets):
        if not sets:
            return [[]]
        result = []
        for head in sets[0]:
            for combo in f(*sets[1:]):
                result.append([head] + combo)
        return result
    
    >>> f([1, 2], [3, 4])
    [[1, 3], [1, 4], [2, 3], [2, 4]]
    

    【讨论】:

    • 非常感谢。我不知道如何使用递归来做到这一点,但这几乎可以工作。我没有注意到,但我没有强调这种输出格式的重要性。如果我想用逗号打印产品,会有类似的概括吗?如:“i1,k1,j1”而不是“i1 k1 j1”。我用它来自动生成一个伪 AMPL 数据转换函数,而且那个语法很挑剔。
    • 我添加了递归方法。你在最里面的 for 循环中做什么取决于你。你有元组p:你不需要做print(*p),你也可以迭代它们,转换它们,或者做任何你喜欢的事情。例如,对于逗号分隔的输出,您可以使用print(','.join(p))
    • 非常感谢您的帮助。现在我看得更清楚了。递归的 sn-p 需要一段时间才能理解,但这就是我的大脑的工作方式:P 谢谢!
    • 递归需要一些时间来包裹头部,但一旦点击,你就会爱上它;)
    • 使用递归来创建产品似乎是个坏主意,因为它需要大约 10 行代码才能以交互方式解决这个问题......
    猜你喜欢
    • 2011-11-03
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2022-01-06
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多