2

I have a list with the following structure:

l = [[[],0]] * 5

each node in the list contains another list:

  • first element in the inner list contains another list
  • second element in the inner list contains wight

I'm trying to add value to the inner list:

index = 0
l[index][0].append('s')

but it add the values 's' to all list (l) values:

l = [[['s'],0], [['s'],0], [['s'],0], [['s'],0], [['s'],0]]
  • why the value 's' duplicates to all the list element ?
  • how can I add the value 's' only to the first inner list (i.e l = [[['s'],0], [[],0], [[],0], [[],0], [[],0]])

Python 3.6.8

user3668129
  • 4,318
  • 6
  • 45
  • 87
  • Because `l[0] is l[1]`. All the list you've created are shallow copies of the same list. It's Python's feature. – StSav012 Aug 26 '20 at 08:02

1 Answers1

5

The problem is the * 5 part of your statement, as it generates 5 aliases of the same list object instead of 5 different list instances. You can imagine your statement written equivalently as follows:

a = [[],0]
l = [a,a,a,a,a]

This follows the evaluation order of your statement and makes it more evident that the list l is in fact a list of 5 aliases.

Replacing the definition of l with a comprehension fixes the issue:

l = [[[],0] for _ in range(5)]

In the comprehension, the loop over range ensures that at each position a new instance is created (check, for instance, l[0] is not l[1]), so that the append can work as you expect it to:

l[0][0].append(1)
print(l)

prints

[[[1], 0], [[], 0], [[], 0], [[], 0], [[], 0]]
GPhilo
  • 18,519
  • 9
  • 63
  • 89