在Python中为任意n嵌套n个循环
假设我有一个任意长的数字列表。我想把列表中的每个数字乘以列表中的每个数字。为此,我会为如下循环嵌套在Python中为任意n嵌套n个循环,python,python-3.x,iteration,Python,Python 3.x,Iteration,假设我有一个任意长的数字列表。我想把列表中的每个数字乘以列表中的每个数字。为此,我会为如下循环嵌套: for x in numbers: for y in numbers: print(x*y) def one_dimension(numbers, n): if (n < 1): return for num in numbers: for next_num in one_dimension(numbers, n-1
:
for x in numbers:
for y in numbers:
print(x*y)
def one_dimension(numbers, n):
if (n < 1):
return
for num in numbers:
for next_num in one_dimension(numbers, n-1):
yield num*next_num
现在,如果我想将列表中的每个数字乘以列表中的每个数字乘以列表中的每个数字,我会这样做:
for x in numbers:
for y in numbers:
for z in numbers:
print(x*y*z)
我的问题是,我正在搜索一个图来寻找一个子图,我需要考虑任意大的子图。要做到这一点,我必须从主图中的边构造每个具有n条边的子图,并且我必须允许n的任意值。如何使用?具有迭代积计算功能(我喜欢reduce(mul,…)
)。如果您需要n
-way产品(在“产品”一词的两种含义中):
上述方法很简单,但当值集较大且n>=3
时,它将不必要地重新计算部分积。可以使用递归函数来避免以下情况:
def compute_products(numbers, repeat):
if repeat == 1:
yield from numbers
return
numbers = tuple(numbers) # Only needed if you want to handle iterator/generator inputs
for prod in compute_products(numbers, repeat-1):
yield from (prod * x for x in numbers)
for prod in compute_products(numbers, n):
print(prod)
具有迭代积计算功能(我喜欢reduce(mul,…)
)。如果您需要n
-way产品(在“产品”一词的两种含义中):
上述方法很简单,但当值集较大且n>=3
时,它将不必要地重新计算部分积。可以使用递归函数来避免以下情况:
def compute_products(numbers, repeat):
if repeat == 1:
yield from numbers
return
numbers = tuple(numbers) # Only needed if you want to handle iterator/generator inputs
for prod in compute_products(numbers, repeat-1):
yield from (prod * x for x in numbers)
for prod in compute_products(numbers, n):
print(prod)
我认为某种递归函数可能会对您有所帮助。这只是输入到堆栈溢出编辑器中的未经测试的伪代码,因此请小心使用这种逐字逐句的方式,但类似于以下内容:
for x in numbers:
for y in numbers:
print(x*y)
def one_dimension(numbers, n):
if (n < 1):
return
for num in numbers:
for next_num in one_dimension(numbers, n-1):
yield num*next_num
def一维(数字,n):
如果(n<1):
返回
对于数字中的num:
对于一维中的下一个数值(数字,n-1):
产量数量*下一个数量
基本思想是函数的每个“级别”调用下一个,然后处理下一个生成的内容。我不知道您对Python的yield
关键字有多熟悉,但是如果您知道它的功能,那么您应该能够修改上面的代码
更新:或者像ShadowRanger在回答中建议的那样使用itertools.product
;这可能是解决您问题的更好方法。我认为某种递归函数可能会对您有所帮助。这只是输入到堆栈溢出编辑器中的未经测试的伪代码,因此请小心使用这种逐字逐句的方式,但类似于以下内容:
for x in numbers:
for y in numbers:
print(x*y)
def one_dimension(numbers, n):
if (n < 1):
return
for num in numbers:
for next_num in one_dimension(numbers, n-1):
yield num*next_num
def一维(数字,n):
如果(n<1):
返回
对于数字中的num:
对于一维中的下一个数值(数字,n-1):
产量数量*下一个数量
基本思想是函数的每个“级别”调用下一个,然后处理下一个生成的内容。我不知道您对Python的yield
关键字有多熟悉,但是如果您知道它的功能,那么您应该能够修改上面的代码
更新:或者像ShadowRanger在回答中建议的那样使用itertools.product
;对于您的问题,这可能是一个更好的解决方案。仅供参考,在Py2中,functools
import forreduce
不是必需的,但是Py3
将reduce
移出了内置名称空间。当然,乘法示例只是一个示例,但是我明白了。你应该测量时间性能,检查递归解决方案对于给定类型的输入是否实际较慢。@J.F.Sebastian:我做了一些计时测试,它绝对不是简单的。对于许多输入来说,递归解决方案的速度会较慢,原因很简单,因为它会执行更多的Python字节码,同时会产生设置Python堆栈框架的成本。对于这里提到的简单案例,itertools.product
解决方案将99%的工作转移到C层(无论如何,在CPython中;PyPy和其他人不会从这样的东西中受益),这使得它的计算成本固定乘数更低,即使大O成本更高。这里的大O成本是什么?仅供参考,在Py2中,functools
import forreduce
不是必需的,但是Py3
将reduce
移出了内置名称空间。当然,乘法示例只是一个示例,但是我明白了。你应该测量时间性能,检查递归解决方案对于给定类型的输入是否实际较慢。@J.F.Sebastian:我做了一些计时测试,它绝对不是简单的。对于许多输入来说,递归解决方案的速度会较慢,原因很简单,因为它会执行更多的Python字节码,同时会产生设置Python堆栈框架的成本。对于这里提到的简单案例,itertools.product
解决方案将99%的工作转移到C层(无论如何,在CPython中;PyPy和其他人不会从这样的东西中受益),这使得它的计算成本固定乘数更低,即使大O成本更高。这里的大O成本是什么?