Type Error (Type Error) when iterating over columns of an array (nested lists) and printing them

0

Given this list of lists:

grid = [['.', '.', '.', '.', '.', '.'],
        ['.', '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', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.']]

I want to create a function that prints the following drawing:

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

For that I used a for in loop in another for in:

def printPic(grid):
    for n in grid:
        for i in grid:
            print(grid[i][n])

And the result is not what was expected:

TypeError: list indices must be integers or slices, not list
    
asked by José Ignacio 01.10.2018 в 23:02
source

1 answer

2

You are mixing two different ways to iterate over a list, indexed and iterated directly with a for in .

When using for elemento in lista: the variable elemento refers to each item in the list directly, not an index. The error is therefore due to the fact that n e i are both a list (one row (nested list) of the list grid ), not an integer as expected from an index. This causes that, in the first iteration for example, you are really doing:

grid[['.', '.', '.', '.', '.', '.']][['.', '.', '.', '.', '.', '.']]

instead of:

grid[0][0]

If you want to use a for in , which is otherwise recommended, you can do the following:

def print_pic(grid):
    for row in zip(*grid):
        print("".join(row)) 

or if you prefer using a single call to print :

def print_pic(grid):
    print("\n".join("".join(row) for row in zip(*grid)))
  • *grid "unpack" the sublists (rows) of the list, so that it is something similar to:

    zip(lista[0], lista[1], ..., lista[n])
    
  • zip allows you to iterate simultaneously on the rows, in the first iteration returns the first element of each row (first column), in the second iteration returns the second element of each row (second column), etc.

  • str.join simply takes all the elements of the column (characters) and joins them together in a single string.

If you want to use indexing, which is possibly your original idea, you can do for example:

def print_pic(grid):
    for i in range(len(grid[0])):
        for j in range(len(grid)):
            print(grid[j][i], end="")
        print()

As before, you can use str.join :

def print_pic2(grid):
    for i in range(len(grid[0])):
        print("".join(grid[j][i] for j in range(len(grid))))

Or more cryptic yet:

def print_pic2(grid):
    print("\n".join("".join(grid[j][i] for j in range(len(grid)))
                                           for i in range(len(grid[0])))) 
>>> print_pic(grid)
..OO.OO..
.OOOOOOO.
.OOOOOOO.
..OOOOO..
...OOO...
....O....
    
answered by 01.10.2018 в 23:40