arrays - using python itertools to manage nested for loops -


i trying use itertools.product manage bookkeeping of nested loops, number of nested loops not known in advance. below specific example have chosen 2 nested loops; choice of 2 clarity, need solution works arbitrary number of loops.

this question provides extension/generalization of question appearing here: efficient algorithm evaluating 1-d array of functions on same-length 1d numpy array

now extending above technique using itertools trick learned here: iterating on unknown number of nested loops in python

preamble:

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  = [] items in product(*joint):     f = trivial_functional(*items)     func_table.append(f) 

at end of above itertools loop, have 12-element, 1-d array of functions, func_table, each element having been built trivial_functional.

question:

suppose given pair of integers, (i_1, i_2), these integers interpreted indices of idx1 , idx2, respectively. how can use itertools.product determine correct corresponding element of func_table array?

i know how hack answer writing own function mimics itertools.product bookkeeping, surely there built-in feature of itertools.product intended purpose?

i don't know of way of calculating flat index other doing yourself. fortunately isn't difficult:

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 

an alternative approach store results in nested array in first place, making translation unnecessary, though more complex:

from functools import reduce 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[:] _ in range(lengths[0])]  func_table = initialize_table(list(map(len, joint))) 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 func_table[2][1] <function> 

Comments

Popular posts from this blog

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

java - Could not locate OpenAL library -

sorting - opencl Bitonic sort with 64 bits keys -