0

I have a question about how to create a list within a list. For example, we use

[[0] * n for _ in range(m)] 

to create a matrix with dimension n*m. However, when I tried the similar thing to create a nested list.

l = [[(0, 1)]] * n 

And then update the l[0], I find the l[1] would also get updated. However, the approach l = [[(0, 1)] for _ in range(n)] produces what I need.

Would you please help me understand this issue?

Thanks for your help.

Follow up: In the dynamic programming, we use [-math.inf]*n to construct a list and then update the values. Why this approach works, but the above approach failed? Thanks.

Qiang Super
  • 323
  • 1
  • 11
  • One multiplies the reference to the same list and puts it into your outer list n times - the other creates m independent new lists and adds them. – Patrick Artner Jul 26 '21 at 14:35
  • There's a good explanation [here](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) – sj95126 Jul 26 '21 at 14:35
  • Thanks, @sj95126. I think that is exactly what I need. – Qiang Super Jul 26 '21 at 14:47
  • Any part of Python I would go through to have a better understanding of this issue? Thanks, @PatrickArtner. – Qiang Super Jul 26 '21 at 14:48

1 Answers1

1

The base list comprehension format

[0 for i in range(some_value)]

does create a list with some_value number of 0s. Using _ instead if i just discards it directly. Now if you want a nested list, first question is, if outer list is rows or columns, however since most often it is matrix[row][column] i will go with it. So lets say you want 10 rows you need 10 items so

[row for i in range(number_rows)]

now what is your definition of a row

[0 for i in range(number_columns)]

if it is initialized with 0s.

Putting the two together, we get

columns, rows = 3,5
l = [[0 for i in range (columns)] for j in range(rows)]

EDIT:

Why [[[0] * n] * m] doesn't work:

When you multiply a mutable object, such as a list, it is not copied, but referenced, meaning, both list entries do point to the same variable in memory. The problem is referred to as deep copy vs shallow copy. It can be observed by calling id of an object.

l = [[1,2,3]]*3
Out[43]: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]

[id(i) for i in l]
Out[44]: [139708443372224, 139708443372224, 139708443372224]

As you can see, all items refer to the same variable, and hence, changing one changes all.

FloLie
  • 1,820
  • 1
  • 7
  • 19