1

I have these lists inside a list that I am trying to number. I also have two variables, row and column, which are taken as input.

lst = row*[column*[0]]

This makes lists inside a list that are filled with zeros, so if row = 6 and column = 10, it would look like:

[[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, 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, 0, 0, 0, 0, 0, 0]] 

How can I change it so it looks like this:

[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],   
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],     
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30],    
[31, 32, 33, 34, 35, 36, 37, 38, 39, 40],     
[41, 42, 43, 44, 45, 46, 47, 48, 49, 50],     
[51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]

Thank You!

7 Answers7

2

I think this would be the most "pythonic" way:

from pprint import pprint

rows = 6
cols = 10

lst = [[(j*cols+i) for i in range(1,cols+1)] for j in range(rows)]

pprint(lst)

Output:

[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
 [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
 [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
 [51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]
martineau
  • 119,623
  • 25
  • 170
  • 301
0

The quick and dirty solution would be:

lst = []
for r in range(row):
    lst.append([])
    for c in range(column):
        lst[r].append(c + r * column)

This can be implemented more cleanly using numpy and reshaping like:

lst = numpy.arange(row * column).reshape(row, column).tolist()
L. MacKenzie
  • 493
  • 4
  • 14
0

Try this:

l = []
for i in range(0, 6):
    row = []
    for j in range(1,11):
        row.append(i*10+j)
    l.append(row)
l
>>>[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
   [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
   [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
   [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
   [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
   [51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]
Aaron Ciuffo
  • 804
  • 8
  • 22
0

Why not using list comprehension as follows:

lst = [[(i+j*column)+1 for i in range(column)] for j in range(row)]
0

You can get this using zip and range.

list(zip(*[iter(range(1, row*column+1))]*column))

This results in a list of tuples but if you need a list of lists, just map list to zip

list(map(list, zip(*[iter(range(1, row*column+1))]*column)))

Results:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49], [50, 51, 52, 53, 54, 55, 56, 57, 58, 59]]

Jab
  • 26,853
  • 21
  • 75
  • 114
  • Quite a bizarre approach, but fun nonetheless. – alkasm Feb 28 '19 at 01:55
  • [this](https://stackoverflow.com/a/54374626/225020) answer to one of my own questions is sooo useful and can be modified quite beautifully sometimes. That's all I did here – Jab Feb 28 '19 at 01:58
  • @AlexanderReynolds Not only is it a fun/bizzare approach but it's about 5x faster than the list comp alternative. See https://repl.it/repls/GracefulThirdOpensource – Jab Feb 28 '19 at 02:12
  • That comparison is wrong, each produces completely different output (the corrected list comp is still slower, though) – alkasm Feb 28 '19 at 02:20
  • I just realized that, why is your answer not producing OP's desired results oops not your answer – Jab Feb 28 '19 at 02:25
  • I didn't provide an answer. – alkasm Feb 28 '19 at 02:26
  • I fixed the repl. Thanks for pointing that out, I'm not saying mine is better I'm just always looking at efficiency I guess – Jab Feb 28 '19 at 02:31
0

The way I would consider approaching this is recognizing that you are generating a list of lists, as opposed to a 2D array.

Also, given your apparent level of experience I think a procedural approach might be a good start for you.

# Your given information
row = 6
col = 10

# Initialize an empty list of lists
lst = []

# Continuously append lists by converting range() objects
i = 1
while i <= (row * col):
  next_i = i + col
  arr.append(list(range(i, next_i)))
  i = i + next_i

Some good next steps would be to investigate the documentation for range() and list(). At first glance they look like functions but they are actually an immutable and a mutable (respectively) sequence type

Note: A comment on your question says

You happen to have created a list with a bunch of references to the same inner list.

To illustrate this, observe what happens in the python interactive interpreter when I try to modify (mutate) one element of the list of lists:

>>> row = 6
>>> column = 10
>>> lst = row*[column*[0]]
>>> lst
[[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, 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, 0, 0, 0, 0, 0, 0]]
>>> lst[0][0] = 999 # set just row 0, column 0 to 999
>>> lst
[[999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

The result is that the first column of every row has been changed to 999. This is because when you "multiplied" the list created by [column*[0]] by row, what actually happened is you got row instances of the same list. So when you refer to one of them, you refer to all of them, in this way. Be careful with this kind of "list multiplication".

0

This works too:

lst = [list(range(1+i*column, 1+(i+1)*column)) for i in range(row)]

Output:

print (lst)
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [31, 32, 33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44, 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]

Explanation:

  1. We're building an outer list, in which each element is an (inner) list of int.
  2. The list comprehension builds the outer list.
  3. The expression before the for loop, which is list(range(1+i*column, 1+(i+1)*column)), represents each element of this outer list. This element, which is a list of int, is first constructed as a range object using range(1+i*column, 1+(i+1)*column). The range object returned by this is then passed to list() to convert it into a list.

Notice that the expression range(1+i*column, 1+(i+1)*column) is intuitive, because, it mirrors the fact that in the i th row, the values will "range" from (1+i*column) to 1+(i+1)*column. For example, in the 6x10 case, when i = 2, the values of the corresponding row will "range" from 1+2*10 to 1+(2+1)*10.

fountainhead
  • 3,584
  • 1
  • 8
  • 17