I was trying to create a 3x3 list of lists, and came up with this surprising behaviour:

# creating a 2D list with an overloaded * operator
mlist3 = [[0]*3]*3
print mlist3  # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
mlist3[0][0] = 1
print mlist3  # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]  oops!
# populate it properly, now it works!
mlist3[0] = [7, 12, 23]
mlist3[1] = [22, 31, 9]
mlist3[2] = [4, 17, 31]
print mlist3  # [[7, 12, 23], [22, 31, 9], [4, 17, 31]]
mlist3[0][0] = 1
print mlist3  # [[1, 12, 23], [22, 31, 9], [4, 17, 31]]

Any explanation?

Yeah, I posted about this, too. Here's the deal:

Because lists are mutable, multiple references to the same list can lead to side effects.

This line:

mlist = [[0]*3]*3

creates a list with three references to the single list [0,0,0].

So when you change that list, all of the references get "automagically" updated.

I haven't decided yet whether this is a "feature" of Python or a "bug." :p

Initializing the array "manually" works, though:

for i in range(3):
    a.append([0,0,0])
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]
>>>

Jeff

Thanks Jeff, so multiplying the sublist [0, 0, 0] by three makes three of exactly the same sublist having the same reference. Appending the list properly won't do that! Wanted to be tricky and paid the price!

The id() test sheds some more light on this ...

mlist3 = [[0]*3]*3
print mlist3  # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# give it the id() test ...
# all three sublists objects show the same address, 10317016 on my machine
# so they are alias copies, not true copies
print mlist3[0], id(mlist3[0])  # [0, 0, 0] 10317016
print mlist3[1], id(mlist3[1])  # [0, 0, 0] 10317016
print mlist3[2], id(mlist3[2])  # [0, 0, 0] 10317016

mlist4 = []
for k in range(3):
    mlist4.append([0, 0, 0])

print mlist4  # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# the id() test shows them to be different objects
print mlist4[0], id(mlist4[0])  # [0, 0, 0] 10316936
print mlist4[1], id(mlist4[1])  # [0, 0, 0] 10316976
print mlist4[2], id(mlist4[2])  # [0, 0, 0] 10317096
Member Avatar for mike_bow

I have this same problem, but with a matrix that's 50x1448. i have to manually enter a list with 1448 zeros? that's a nasty surprise.

If by manually you mean with 2 for loops or a list comprehension.

listX = [[0 for i in range(1448)] for j in range(50)]
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.