1

I recently picked up Python and I am alternating between this tutorial and a book called Automate The Boring Stuff With Python.

I find the book quite easy to understand and the exercises are fun. There is one in particular that I just solved but honestly, I am not satisfied with my answer.

In the question, one is given a grid as follows:

grid = [['.', '.', '.', '.', '.', '.'],
        ['.', '0', '0', '.', '.', '.'],
        ['0', '0', '0', '0', '.', '.'],
        ['0', '0', '0', '0', '0', '.'],
        ['.', '0', '0', '0', '0', '0'],
        ['0', '0', '0', '0', '0', '.'],
        ['0', '0', '0', '0', '.', '.'],
        ['.', '0', '0', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.']]

Using loops only, one is then required to produce the following output:

..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....

My solution (which works) to this problem is as follows:

for y in range(0,len(grid[0])):
    for x in range(0, len(grid)):
        print(grid[x][y], end='')

    print()

My problem is the grid[0]. I have tried to generalize the code to accommodate scenarios in which the lists within grid are of different values, but failed.

My question, therefore, is how can I retrieve the len of grid[0] in general variable terms?

In other words, how can I retrieve the length of a list within a list?

Mikev
  • 2,012
  • 1
  • 15
  • 27
Mexen
  • 198
  • 2
  • 12
  • So, do you want a nice solution with `zip` or are we stuck to only `for` and `print` here? :) – timgeb Nov 14 '18 at 08:32
  • Kind of confusing what exactly you are asking, but just do `len(grid(row_number))` – iz_ Nov 14 '18 at 08:33
  • @Tomothy32 that's exactly what I did. But how would I loop through list values of varying length? Let's imagine that I do not know their lengths either. – Mexen Nov 14 '18 at 08:49
  • 1
    @timgeb Thanks. The book is yet to introduce zip so just for/while and print. – Mexen Nov 14 '18 at 08:51
  • Do you want something like `for sublist in grid: len(sublist)`? – iz_ Nov 14 '18 at 09:00
  • That sounds like it. Could you please share a working example, and then I will apply to my particular problem? @Tomothy32 – Mexen Nov 14 '18 at 13:51

5 Answers5

2

For example taking the longes of all the content list:

>>> grid = [['.', '.', '.', '.', '.', '.'],
...         ['.', '0', '0', '.', '.', '.'],
...         ['0', '0', '0', '0', '.', '.'],
...         ['0', '0', '0', '0', '0', '.'],
...         ['.', '0', '0', '0', '0', '0'],
...         ['0', '0', '0', '0', '0', '.'],
...         ['0', '0', '0', '0', '.', '.'],
...         ['.', '0', '0', '.', '.', '.'],
...         ['.', '.', '.', '.', '.', '.']]
>>> 
>>> max(map(len, grid))
6

BTW, a pythonic way of solving that (without loops) would look like this list(zip(*grid)):

>>> for l in zip(*grid):
...     print("".join(l))
... 
..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....
Netwave
  • 40,134
  • 6
  • 50
  • 93
2

You don't actually need to retrieve length.

You can do it in one line without knowing dimensions:

print('\n'.join(map(lambda x: ''.join(x), zip(*grid))))

Step by step:

  1. zip(*grid) will transpose your 2-d array
>>> list(zip(*grid))
[('.', '.', '0', '0', '.', '0', '0', '.', '.'),
 ('.', '0', '0', '0', '0', '0', '0', '0', '.'),
 ('.', '0', '0', '0', '0', '0', '0', '0', '.'),
 ('.', '.', '0', '0', '0', '0', '0', '.', '.'),
 ('.', '.', '.', '0', '0', '0', '.', '.', '.'),
 ('.', '.', '.', '.', '0', '.', '.', '.', '.')]
  1. map(lambda x: ''.join(x), zip(*grid)) will join every line
>>> list(map(lambda x: ''.join(x), zip(*grid)))
['..00.00..', '.0000000.', '.0000000.', '..00000..', '...000...', '....0....']
  1. And finally '\n'.join joins with separator as new line
>>> print('\n'.join(map(lambda x: ''.join(x), zip(*grid))))
..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....

Note: we could also omit 3rd step by printing with sep='\n, however in Python3: Why does map return a map object instead of a list in Python 3? and we would need to convert it to list before printing it. Like so:

print(list(map(lambda x: ''.join(x), zip(*grid))), sep='\n')
vishes_shell
  • 22,409
  • 6
  • 71
  • 81
  • 1
    Very interesting, thank you for sharing! At the time of writing this comment, I have not read about zip yet so implementation is based on loops and print alone but it is one to look out for, for sure! – Mexen Nov 14 '18 at 13:51
1

Another way of doing this is to start by transposing the grid, then just loop over the elements of each row

 grid = [['.', '.', '.', '.', '.', '.'],
         ['.', '0', '0', '.', '.', '.'],
         ['0', '0', '0', '0', '.', '.'],
         ['0', '0', '0', '0', '0', '.'],
         ['.', '0', '0', '0', '0', '0'],
         ['0', '0', '0', '0', '0', '.'],
         ['0', '0', '0', '0', '.', '.'],
         ['.', '0', '0', '.', '.', '.'],
         ['.', '.', '.', '.', '.', '.']]
  grid2=zip(*grid)
 # print(grid2)
  for row in grid2:
     for el in row:
         print(el, end='')
     print('\n')
robotHamster
  • 609
  • 1
  • 7
  • 24
1

If you look at your desired output, you'll observe that final matrix is transpose of your given list.

The transpose of a matrix could be found by using numpy transpose function.

You could use a list comprehension in combination with join method in order to achieve what you want.

import numpy as np
transpose = np.array(grid).transpose()
print('\n'.join([''.join(row) for row in transpose]))

Output

..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
1

If you really must get the length of a list in a list, just use len(grid[index]):

for i in range(len(grid)):
    for j in range(len(grid[i])):
        print(mylist[i][j], end='')
    print()

However, it is easier to to iterate over the elements of the list than to get the indexes of the list. For example, instead of the above solution, use

for row in mylist:
    for element in row:
         print(element, end='')
    print()
iz_
  • 15,923
  • 3
  • 25
  • 40