An iterator for a variable number of nested loops

I am trying to write an iterator for something like this (simplified from the original problem):

import numpy as np

class IterableNumber:
  def __init__(self, digits):
    self.digits = digits
    self.zero_indices = np.where(digits == 0)[0]
  def __iter__(self):
    return self
  def next(self):
    # For each index in self.zero_indices, loop 1 through 9?
    pass
  # Other methods omitted

IterableNumber accepts an array of numbers, but "0" is a wild card. When I scroll this object, I want each digit "0" to go through the range from 1 to 9, i.e.

num = IterableNumber(np.array([5, 5, 0, 5, 0]))
for digits in num:
  print digits

should print

[5, 5, 1, 5, 1]
[5, 5, 1, 5, 2]
...
[5, 5, 1, 5, 9]
[5, 5, 2, 5, 1]
[5, 5, 2, 5, 2]
...
...
[5, 5, 9, 5, 9]

Writing this iterator for the general case seems to require recursion to take care of a variable number of nested loops (one for every 0), as the other threads on this site suggest. But how to write such a recursive function in the context of the iterator next () function? Or maybe there is another way to solve this problem? Any insight would be appreciated :)

I am on python 2.7.3 if that matters.

+4
1

itertools.product :

import numpy as np

from itertools import product

class IterableNumber:
    def __init__(self, digits):
        self.digits = digits
        self.zero_indices = np.where(self.digits==0)[0]
        self.length = len(self.zero_indices)

    def __iter__(self):
        for x in product(range(10), repeat=self.length):
            self.digits[self.zero_indices] = np.array(x)
            yield self.digits

Demo:

>>> for x in IterableNumber(np.array([5, 5, 0, 5, 0])):
    print x
...     
[5 5 0 5 0]
[5 5 0 5 1]
[5 5 0 5 2]
[5 5 0 5 3]
[5 5 0 5 4]
[5 5 0 5 5]
[5 5 0 5 6]
[5 5 0 5 7]
[5 5 0 5 8]
[5 5 0 5 9]
...
...
[5 5 9 5 3]
[5 5 9 5 4]
[5 5 9 5 5]
[5 5 9 5 6]
[5 5 9 5 7]
[5 5 9 5 8]
[5 5 9 5 9]
>>> 
+3

All Articles