Zaruya Zaruya - 8 months ago 33
Python Question

Python: Empty spaces(those with 0's) in lists

I am trying to create a function which returns the empty slots in this list:

grid = [[0,0,0,4],[0,0,4,2],[2,4,4,2],[0,8,4,2]]

The empty slots in this case is those slots with zeroes.

This was my program for it:

def empty_slots():
lst = []
for i in grid:
for j in grid:
if j == 0:
lst = lst + [(i,j)]
return lst

However, when I run this program I get an empty list
. And the function should output:
[(0,0), (0,1), (0,2), (1,0), (1,1), (3,0)]
. Note: I'm using Python 2.7.


for i in grid: iterates over the items in grid, it doesn't iterate over their indices. However, you can get the indices as you iterate over the items of an iterable via the built-in enumerate function:

def empty_slots(grid):
    return [(i, j) for i, row in enumerate(grid) 
        for j, v in enumerate(row) if not v]

grid = [[0,0,0,4],[0,0,4,2],[2,4,4,2],[0,8,4,2]]



[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (3, 0)]

Here's the same thing using "traditional" for loops instead of a list comprehension.

def empty_slots(grid):
    zeros = []
    for i, row in enumerate(grid):
        for j, v in enumerate(row):
            if v == 0:
                zeros.append((i, j))
    return zeros

In this version I use the explicit test of v == 0 instead of not v; the latter will test true if v is any "falsey" value, eg, 0, or an empty string, list, tuple, set or dict.

You don't need enumerate to do this. You could do this:

def empty_slots(grid):
    zeros = []
    for i in range(len(grid)):
        row = grid[i]
        for j in range(len(row)):
            if row[j] == 0:
                zeros.append((i, j))
    return zeros

However, it is considered more Pythonic to iterate directly over the items in an iterable, so this sort of thing is generally avoided, when practical:

for i in range(len(grid)):

Occasionally you will need to do that sort of thing, but usually code like that is a symptom that there's a better way to do it. :)