-1

Possible dupe: Append value to one list in dictionary appends value to all lists in dictionary

I've encountered a problem in using nested arrays, where all elements are updated, when I only want to append to a specific index.

x = [[]] * 6
x[0].append(1)
# expected: [[1], [], [], [], [], []]
# result: [[1], [1], [1], [1], [1], [1]]

What I'm guessing is that x[0] returns [], which turns the statement to [].append(1) and updates all empty lists. This is supported by the fact that non-empty sets will not be changed.

x = [[]] * 6
x[1] = [0]
x[0].append(1)
# [[1], [0], [1], [1], [1], [1]]

I currently do this workaround to assign the value:

x = [[]] * 6
y = x[0].copy()
y.append(1)
x[0] = y

I want to understand 1) why python would evaulate the x[0] bit and make [].append() apply to multiple elements in the list, if my theory is correct and 2) if there is a better way to add values in a nested list.

SaNoy SaKnoi
  • 25
  • 1
  • 3
  • Try to change this `x = [[] for _ in range(6)]` and see the difference. And it's helpful to see what's the `difference` in https://pythontutor.com/ – Daniel Hao Jun 22 '22 at 00:54
  • 1
    Related: https://nedbatchelder.com/text/names.html – CrazyChucky Jun 22 '22 at 00:56
  • 1
    _"This is supported by the fact that non-empty sets will not be changed"_: 1. There are no sets here, only lists. Terminology is important, because `set` is actually a thing in python whose behavior is distinct from a `list`. 2. Your statement is not true. E.g., try with `x = [[1]] * 6` – Pranav Hosangadi Jun 22 '22 at 01:02

3 Answers3

0

In line x = [[]] * 6, you creating a list x with 6 reference to the same inner list []. To make it simple, x = [[]] * 6 is equivalent to:

inner_list = []
x = []
for _ in range(6):
    x.append(inner_list) # here same 'inner_list' is appended 6 times

So, what you want to do here is:

x = []
for _ in range(6):
    inner_list = []
    x.append(inner_list) # here you are creating 6 different 'inner_list' and appending it to 'x'
BhusalC_Bipin
  • 801
  • 3
  • 12
0

The statement x = [[]] * 6 creates a list with 6 references to the same list. Thus, when you append an element to any of them, the others are also updated.

When you say x[1] = [0], you've replaced x[1] entry with a new list. Thus, when updating another entry this new list will not be updated.

If you want to create a list that consists of 6 independent lists, do [[] for _ in range(6)]

Mikhail Genkin
  • 3,247
  • 4
  • 27
  • 47
0

In python, list, dict, set, tuples are collection data types. It means, if you declare a variable based on collection, you have the address of the collection.

If you duplicate a collection, you have the same address for every duplication. It is the case when you do it: x = [[]] * 6

If you modify one element, it affects all of his copies.

mathonweb
  • 1
  • 1