3

Let's say I want to create a list of lists to be filled later, that looks like that:

[['', ''], ['', ''], ['', '']]

I can create it like so:

rows=3
cols=2

A=['']*cols
B=[A[:]]*rows

However, the inner lists are the same object, as can be seen:

B[0][0]='!'
print (B)

Output:

[['!', ''], ['!', ''], ['!', '']]

This occurs even though I used B=[A[:]]*rows rather than B=[A]*rows; using B=[A][:]*rows does not solve the problem.

If A[:] should efficiently create a full copy (rather than just a reference) by slicing A, then why does this occur?

P.S.

Obviously this can be easily solved for example by:

this_text=[]
temp=[]
for i in range(cols):
    A.append('')
for i in range(rows):
    B.append(A[:])

My aim is improved understanding, not creating this specific list of lists.

Lafayette
  • 568
  • 4
  • 19

2 Answers2

3

This will prevent B from being a list of copies, since it creates a new A[:] for each x:

B=[A[:] for x in range(rows)]
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
3
B=[A[:]]*rows

takes the same list instance ['' * cols] row times.

Changing one reference to said instance will affect all references.

Use a comprehension instead to create independent lists.

B=[A[:] for x in range(rows)]
ParthS007
  • 2,581
  • 1
  • 22
  • 37