具有固定范围的可变数量的嵌套for循环

时间:2018-03-15 18:12:20

标签: python-3.x recursion

我正在寻找一种方法来使用可变数量的嵌套for循环而不是以下代码。例如,如果变量 n 表示嵌套for循环的数量且 n = 3 ,我的代码将为:

p = []
for i in range(26):
  for j in range(26):
    for k in range(26):
      p.append([i,j,k])

相反,如果 n = 2 ,我的代码将是:

p = []
for i in range(26):
  for j in range(26):
    p.append([i,j])

我知道这可以通过递归来完成,但我对如何做到这一点感到有点困惑。

2 个答案:

答案 0 :(得分:1)

培养解决这些问题的技能非常重要。在这种情况下,Python包含itertools.product,但是下次您需要编写特定于您的程序的行为时会发生什么?还有另外一个神奇的内置功能吗?也许其他人会发布第三方图书馆来解决你的问题?

下面,我们将product设计为一个简单的递归函数,接受一个或多个列表。

def product (first, *rest):
  if not rest:
    for x in first:
      yield (x,)
  else:
    for p in product (*rest):
      for x in first:
        yield (x, *p)

for p in product (range(2), range(2), range(2)):
  print ('x: %d, y: %d z: %d' % p)

# x: 0, y: 0 z: 0
# x: 1, y: 0 z: 0
# x: 0, y: 1 z: 0
# x: 1, y: 1 z: 0
# x: 0, y: 0 z: 1
# x: 1, y: 0 z: 1
# x: 0, y: 1 z: 1
# x: 1, y: 1 z: 1

假设您需要更传统的迭代排序,您可以通过使用辅助loop帮助程序来完成此操作

def product (first, *rest):
  def loop (acc, first, *rest):
    if not rest:
      for x in first:
        yield (*acc, x)
    else:
      for x in first:
        yield from loop ((*acc, x), *rest)
  return loop ((), first, *rest)

for p in product (range(2), range(2), range(2)):
  print ('x: %d, y: %d z: %d' % p)

# x: 0, y: 0 z: 0
# x: 0, y: 0 z: 1
# x: 0, y: 1 z: 0
# x: 0, y: 1 z: 1
# x: 1, y: 0 z: 0
# x: 1, y: 0 z: 1
# x: 1, y: 1 z: 0
# x: 1, y: 1 z: 1

答案 1 :(得分:0)

这样的事情应该有效:

import itertools

n=3
fixed=26
p = list(itertools.product(range(fixed), repeat=n))

此解决方案使用itertools的优化函数,因此它应该非常快。

请注意itertools.product返回迭代器,因此需要将其转换为数组。