Can I use a decorator to loop through nested list?
<p>I am having to loop through a 2-dimensional grid (rows and columns) repeatedly to execute various functions at each cell in the grid.  Each time I want to apply another to the cells, I have to code the nested loop...</p>

<pre><code>for row in rows:
   for col in row:
      func(col)
</code></pre>

<p>So to avoid repeating myself, I started with this (old school - Python 2.7.x)</p>

<pre><code>#version 1
grid = [[1,2,3,],[4,5,6],[7,8,9]]
def loop(grid,func):
    results = []
    for row in grid:
        for col in row:
            results.append(func(col))
    return results
def func(x):
    return x+1
results = loop(grid,func)
</code></pre>

<p>output:</p>

<pre><code>[2, 3, 4, 5, 6, 7, 8, 9, 10]
</code></pre>

<p>To me, passing a function as argument into another function smelled of a decorator use case. But I haven't figured out how to make it work - passing the grid argument into any wrapper function is tripping me up.</p>

<p>The only improvement I've made to the above is using <code>map</code></p>

<pre><code>#version 2
def func(x):
    return x+1
def loop(grid,func):
    return map(func,[col for row in grid for col in row])
</code></pre>

<p>So my question is can it be done using a decorator and how? (<strong>Etiquette alert</strong>: Which is the better way?)</p>

<p>Sure, you can write a decorator to transform a function that works on a single element into one that works on a grid using a nested loop:</p>

<pre><code>def gridfunc(func):
    def wrapper(grid):
        results = []
        for row in grid:
            for col in row:
                results.append(func(col))
        return results
    return wrapper

@gridfunc
def foo(x):
    return x+1

grid = [[1,2,3,],[4,5,6],[7,8,9]]
results = foo(grid)
</code></pre>

<p>The only downside to this is that the original function <code>foo</code> is not (easily) available if you want to run it on a single value rather than a grid of them. If you want to be able to use both versions, you could use <code>gridfoo = gridfunc(foo)</code> instead of the <code>@decorator</code> syntax.</p>

python decorator