Skip to main content
 首页 » 编程设计

python之使用 python itertools 来管理嵌套的 for 循环

2025年05月04日42yxwkf

我正在尝试使用 itertools.product 来管理一些嵌套 for 循环的簿记,其中嵌套循环的数量是事先不知道的。下面是一个具体的例子,我选择了两个嵌套的 for 循环;选择两个只是为了清楚起见,我需要的是一个适用于任意数量循环的解决方案。

这个问题提供了此处出现的问题的扩展/概括: Efficient algorithm for evaluating a 1-d array of functions on a same-length 1d numpy array

现在我正在使用我在此处学到的 itertools 技巧扩展上述技术: Iterating over an unknown number of nested loops in python

前言:

from itertools import product 
 
def trivial_functional(i, j): return lambda x : (i+j)*x 
 
idx1 = [1, 2, 3, 4] 
idx2 = [5, 6, 7] 
joint = [idx1, idx2] 
 
func_table  = [] 
for items in product(*joint): 
    f = trivial_functional(*items) 
    func_table.append(f) 

在上面的 itertools 循环结束时,我有一个 12 元素的一维函数数组 func_table,每个元素都是从 trivial_functional 构建的。

问题:

假设我有一对整数 (i_1, i_2),其中这些整数分别被解释为 idx1idx2 的索引。我如何使用 itertools.product 来确定 func_table 数组的正确对应元素?

我知道如何通过编写自己的模仿 itertools.product 簿记的函数来破解答案,但肯定有 itertools.product 的内置功能正是用于此目的?

请您参考如下方法:

除了自己计算之外,我不知道有什么方法可以计算平面指数。幸运的是,这并不难:

def product_flat_index(factors, indices): 
  if len(factors) == 1: return indices[0] 
  else: return indices[0] * len(factors[0]) + product_flat_index(factors[1:], indices[1:]) 
 
>> product_flat_index(joint, (2, 1)) 
9 

另一种方法是首先将结果存储在一个嵌套数组中,这样就不需要转换了,尽管这更复杂:

from functools import reduce 
from operator import getitem, setitem, itemgetter 
 
def get_items(container, indices): 
  return reduce(getitem, indices, container) 
 
def set_items(container, indices, value): 
  c = reduce(getitem, indices[:-1], container) 
  setitem(c, indices[-1], value) 
 
def initialize_table(lengths): 
  if len(lengths) == 1: return [0] * lengths[0] 
  subtable = initialize_table(lengths[1:]) 
  return [subtable[:] for _ in range(lengths[0])] 
 
func_table = initialize_table(list(map(len, joint))) 
for items in product(*map(enumerate, joint)): 
  f = trivial_functional(*map(itemgetter(1), items)) 
  set_items(func_table, list(map(itemgetter(0), items)), f) 
 
>>> get_items(func_table, (2, 1)) # same as func_table[2][1] 
<function>