【问题标题】:Partial nest for loops部分嵌套循环
【发布时间】:2015-06-18 01:45:06
【问题描述】:

注意:更正的问题!

众所周知,itertools 允许轻松创建嵌套的for 使用itertools.product 循环。但以下是我想要但还不能做的事情。使用

lfl = int(input( "length of first loop: "))
nol = int(input( "number of loops: "))

原因:

  • 循环长度:12
  • 循环数:4

我想要一个等价于:

for i1 in range(1,12):
    for i2 in range(i1,12):
        for i3 in range(i2,12):
            for i4 in range(i3,12):
                function(i1,i2,i3,i4)

itertools.product 确实有很多人。

或者更一般的问题,nol 导致创建 func_1(x), func_2(x,y), .... func_nol-1(x,y,...) 并且代码需要是相当于:

for i1 in range(1,12):
    for i2 in range(func_1(i1),12):
        for i3 in range(func_2(i1,i2),12):
            for i4 in range(func_3(i1,i2,i3),12):
                function(i1,i2,i3,i4)

还有一个更进一步的概括是

for i1 in range(1,12):
    for i2 in range(start_func_1(i1, *global),end_func_(12, *global)):
        for i3 in range(start_func_2(i1,i2,*global),end_func_2(12,*global):
            for i4 in range(start_func_3  etc....

【问题讨论】:

  • 你所说的产品是什么意思。?
  • @timothy 你是如何使用product的?
  • @Kasra 我被内部循环范围打错了,我已经编辑了这个问题。
  • @matsjoyce,我很抱歉,使用product 的一种方法是为每个循环使用一个上限范围,因此作为上述问题的一个示例,我对“很多' 是 product 超过 [1,12] 四次包括我正在寻找的结果。但还有很多我不想要的。
  • 你确定要range(1, 12)吗?您将lfl = 12 称为第一个循环的长度,但该范围的长度为11。

标签: python loops for-loop recursion nested


【解决方案1】:

对于您更正的问题,在您的范围列表中尝试使用combinations_with_replacement 而不是product

from itertools import combinations_with_replacement

nums = [10, 11, 12, 13]
for c in combinations_with_replacement(nums, 3):
    print c

打印

(10, 10, 10)
(10, 10, 11)
(10, 10, 12)
(10, 10, 13)
(10, 11, 11)
(10, 11, 12)
(10, 11, 13)
(10, 12, 12) 
...

【讨论】:

  • 不幸的是,tool 返回 (n+r-1)! / r! / (n-1)! 不同的元组。因此,在我更正的示例中,这将再次大幅过冲。如果元组具有正确的条件(即 (i4>=i3>=i2>=i1)
  • 好吧,我不明白这缺少什么。你想要i1 ≤ i2 ≤ i3 ≤ i4,对吧?如果您传递它,此代码将准确生成它所持有的序列,例如range(1, 12)4
  • 您的评论完全符合我在第一个示例中给出的标准,我的思绪已经转移到一般问题上。但是你的答案很漂亮而且是正确的。不幸的是,说 i4>i3>i2>1 的微小变化会立即导致问题。 SO combination_with_replacement 完全等同于我的第一个问题。但是,我应该马上问我的一般性问题,因为那是我真正感兴趣的!我必须记住要完全准确!
  • 如果i4 > i3 > i2 > i1 是您真正需要的,请尝试itertools.combinations。否则,使用函数列表的函数将变得难以理解;你确定你需要这么多的概括吗?
  • 其实是的。我正在查看的问题的最简单情况是用您的解决方案解决的,现在我有一个很好的程序正在运行,它可以在用户指定的间隔上找到任意整数集,这些整数会产生某些统计属性,比如整数值均值和标准偏差。另一个是使用某些复值函数找到 nth-derivatives 的根的界限。这些界限,下限和上限,根据其他根有很大的不同。对于大型多项式,迭代循环可能会变得非常多,整数范围也会变得非常大。
【解决方案2】:

这与您提供的代码完全相同:

from itertools import product

lfl = 12
nol = 4

ranges = (range(i, lfl) for i in range(1, nol + 1))
args = product(*ranges)

for arg in args:
    function(*arg)

它使用generator expression 构建用于循环的范围列表以传递给itertools.productargument list unpacking 以将单个参数元组作为单独的参数传递给函数/ 到product()

演示:

from itertools import product

def function(*args):
    return args

results_nested = []
results_product = []

for i1 in range(1, 12):
    for i2 in range(2, 12):
        for i3 in range(3, 12):
            for i4 in range(4, 12):
                results_nested.append(function(i1, i2, i3, i4))

lfl = 12
nol = 4

ranges = (range(i, lfl) for i in range(1, nol + 1))
args = product(*ranges)

for arg in args:
    results_product.append(function(*arg))


assert results_nested == results_product

【讨论】:

  • 非常抱歉,我的问题有误。其实是错别字。我很欣赏答案,尤其是我不知道的 *args 的发现。我打算以答案形式重新提出问题。
  • @timothysorenson 没问题,它发生了 ;-) 感谢您让我知道并更新问题。
【解决方案3】:

您可以使用 product 执行此操作 - 您只需在初始准备步骤中创建循环的“维度”:

from itertools import product

length = 12
loops = 4

ranges = [range(x+1,length) for x in range(loops)]

def f(x):  # accepts a tuple, since the number of arguments may vary
    print("f(%s)" % repr(x))

for t in product(*ranges):
    f(t)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    • 2010-12-31
    相关资源
    最近更新 更多