【问题标题】:Variable number of nested for loops with fixed range具有固定范围的可变数量的嵌套 for 循环
【发布时间】:2018-03-15 18:12:20
【问题描述】:

我正在寻找一种方法来拥有可变数量的嵌套 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])

我知道这可以使用递归来完成,但我对如何去做这件事有点困惑。

【问题讨论】:

    标签: python-3.x recursion


    【解决方案1】:

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

    下面,我们将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
    

    【讨论】:

      【解决方案2】:

      这样的事情应该可以工作:

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

      这个方案使用了itertools的优化功能,所以应该挺快的。

      请注意itertools.product 返回一个迭代器,因此需要对其进行转换以获得一个数组。

      【讨论】:

      • 您可以将[x for x in iterable] 替换为list (iterable)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      相关资源
      最近更新 更多