Search code examples
python-3.xlistpython-3.7

Why I am not able to use a nested loop in a list of lists?


I am trying to solve a project from the book Automate the boring stuff with Python, chapter 4, Project:Character picture grid.

I am not able to loop through the code and print the pattern the book says. Here is my code:

gridlines = [['.', '.', '.', '.', '.', '.'],  # 0, 0
             ['.', 'O', 'O', '.', '.', '.'],
             ['O', 'O', 'O', 'O', '.', '.'],
             ['O', 'O', 'O', 'O', 'O', '.'],
             ['.', 'O', 'O', 'O', 'O', 'O'],
             ['O', 'O', 'O', 'O', 'O', '.'],
             ['O', 'O', 'O', 'O', '.', '.'],
             ['.', 'O', 'O', '.', '.', '.'],
             ['.', '.', '.', '.', '.', '.']]

def grid_line(grid_func):
    for i in grid_func[0:8]:
        for grid_functioning in grid_func[0:5]:
                print(i, end='')

grid_line(gridlines)

The book is saying me to print this pattern:

..OO.OO..
.OOOOOOO.
.OOOOOOO.
..OOOOO..
...OOO...
....O....

Solution

  • That pattern seems to be starting at the top left and initially going down rather than across(a). That means you cannot process each column within a row but must instead process each row within a column.

    Assuming, it's guaranteed to be rectangular, that can be done with(b):

    def grid_line(grid_func):
        for index in range(len(grid_func[0])): # square: do each column
            for row in grid_func:              # do each row within that column
                print(row[index], end="")      # output the cell, no line feed
            print()                            # go to next line after column
    

    You'll notice I've removed the [0:n] bits since you don't need a slice, the entire row/column should be used. In any case, the 5 and 8 values you had were wrong, since the n is one beyond what you want to process, so you would have skipped the final row/column.


    (a) Technically, it could start at bottom left and go up (since it's symmetrical) but I've opted for the simpler case.


    (b) It could also be done with the more Pythonic list comprehension and string join method below, but I'd probably hold off on that until you're a bit more comfortable with the language :-)

    def grid_line(grid):
        print("\n".join(["".join([row[idx] for row in grid]) for idx in range(len(grid[0]))]))