967

I created a list of lists:

>>> xs = [[1] * 4] * 3
>>> print(xs)
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

Then, I changed one of the innermost values:

>>> xs[0][0] = 5
>>> print(xs)
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]

I expected this to only affect the first sublist, not all of them. That is:

>>> print(xs)
[[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

Why did every first element of every sublist change to 5?


See also:

Anerdw
2,6743 gold badges18 silver badges44 bronze badges
asked Oct 27, 2008 at 14:57
5
  • Note that the same logic applies to a list of dicts, because of the same fundamental problem of aliasing a mutable object. See stackoverflow.com/questions/46835197/… for a more specific question. Commented Dec 16, 2021 at 23:17
  • 1
    Are there more specific questions for when the list of lists is created in other ways (but has the same problem)? For example, by using .append in a loop? Commented May 3, 2022 at 14:52
  • See also stackoverflow.com/questions/2612802 for a question focused on avoiding this kind of aliasing after the fact. Commented Jun 4, 2022 at 12:40
  • 1
    Related: nedbatchelder.com/text/names.html Commented Jun 22, 2022 at 0:59
  • 1
    To use a matrix in Python, just go to numpy. A list of list is really cumbersome and slow. Commented Nov 17, 2023 at 3:34

18 Answers 18

820

When you write [x]*3 you get, essentially, the list [x, x, x]. That is, a list with 3 references to the same x. When you then modify this single x it is visible via all three references to it:

x = [1] * 4
xs = [x] * 3
print(f"id(x): {id(x)}")
# id(x): 140560897920048
print(
 f"id(xs[0]): {id(xs[0])}\n"
 f"id(xs[1]): {id(xs[1])}\n"
 f"id(xs[2]): {id(xs[2])}"
)
# id(xs[0]): 140560897920048
# id(xs[1]): 140560897920048
# id(xs[2]): 140560897920048
x[0] = 42
print(f"x: {x}")
# x: [42, 1, 1, 1]
print(f"xs: {xs}")
# xs: [[42, 1, 1, 1], [42, 1, 1, 1], [42, 1, 1, 1]]

To fix it, you need to make sure that you create a new list at each position. One way to do it is

[[1]*4 for _ in range(3)]

which will reevaluate [1]*4 each time instead of evaluating it once and making 3 references to 1 list.


You might wonder why * can't make independent objects the way the list comprehension does. That's because the multiplication operator * operates on objects, without seeing expressions. When you use * to multiply [[1] * 4] by 3, * only sees the 1-element list [[1] * 4] evaluates to, not the [[1] * 4 expression text. * has no idea how to make copies of that element, no idea how to reevaluate [[1] * 4], and no idea you even want copies, and in general, there might not even be a way to copy the element.

The only option * has is to make new references to the existing sublist instead of trying to make new sublists. Anything else would be inconsistent or require major redesigning of fundamental language design decisions.

In contrast, a list comprehension reevaluates the element expression on every iteration. [[1] * 4 for n in range(3)] reevaluates [1] * 4 every time for the same reason [x**2 for x in range(3)] reevaluates x**2 every time. Every evaluation of [1] * 4 generates a new list, so the list comprehension does what you wanted.

Incidentally, [1] * 4 also doesn't copy the elements of [1], but that doesn't matter, since integers are immutable. You can't do something like 1.value = 2 and turn a 1 into a 2.

Mateen Ulhaq
27.6k21 gold badges120 silver badges154 bronze badges
answered Oct 27, 2008 at 15:03
6
  • 47
    I am surprised that no body points out that, the answer here is misleading. [x]*3 store 3 references like [x, x, x] is only right when x is mutable. This does't work for e.g. a=[4]*3, where after a[0]=5, a=[5,4,4]. Commented May 22, 2015 at 0:16
  • 71
    Technically, it's still correct. [4]*3 is essentially equivalent to x = 4; [x, x, x]. It's true, though, that this will never cause any problem since 4 is immutable. Also, your other example isn't really a different case. a = [x]*3; a[0] = 5 won't cause problems even if x is mutable, since you're not modifying x, only modifying a. I wouldn't describe my answer as misleading or incorrect - you just can't shoot yourself in the foot if you're dealing with immutable objects. Commented May 22, 2015 at 8:04
  • 36
    @Allanqunzi you are wrong. Do x = 1000; lst = [x]*2; lst[0] is lst[1] -> True. Python does not distinguish between mutable and immutable objects here whatsoever. Commented Apr 17, 2016 at 18:08
  • 1
    can anyone find documents about the * operator in docs.python.org? i tried but cnanot find any. Commented Mar 31, 2022 at 1:46
  • 1
    @LeiYang It's listed under Common Sequence Operations Commented May 22, 2022 at 4:56
184
size = 3
matrix_surprise = [[0] * size] * size
matrix = [[0]*size for _ in range(size)]

Live visualization using Python Tutor:

Frames and Objects

answered Aug 26, 2013 at 23:17
5
  • 1
    So, why if we write matrix= [[x] * 2] doesn't make 2 elemnts for the same object like the example you describe, it seems to be the same concept, what am i missing? Commented Jul 1, 2017 at 17:55
  • 1
    @AhmedMohamed Indeed it does make a list with two elements of the exact same object that x refers to. If you make a globally unique object with x = object() and then make matrix = [[x] * 2] these does come as true: matrix[0][0] is matrix[0][1] Commented Jul 2, 2017 at 13:13
  • @nadrimajstor so why the change in matrix[0] doesn't affect matrix[1] like the example above with 2d matrix. Commented Jul 2, 2017 at 13:31
  • @AhmedMohamed Surprise come when you make a "copy" of mutable sequence (in our example it is a list) so if a row = [x] * 2 than a matrix = [row] * 2 where both rows are exactly the same object, and now changes to one row matrix[0][0] = y suddenly reflect in the other one (matrix[0][0] is matrix[1][0]) == True Commented Jul 2, 2017 at 15:44
  • @AhmedMohamed Take a look at Ned Batchelder - Facts and Myths about Python names and values as it might offer a better explanation. :) Commented Jul 2, 2017 at 16:11
74

Actually, this is exactly what you would expect. Let's decompose what is happening here:

You write

lst = [[1] * 4] * 3

This is equivalent to:

lst1 = [1]*4
lst = [lst1]*3

This means lst is a list with 3 elements all pointing to lst1. This means the two following lines are equivalent:

lst[0][0] = 5
lst1[0] = 5

As lst[0] is nothing but lst1.

To obtain the desired behavior, you can use a list comprehension:

lst = [ [1]*4 for n in range(3) ]

In this case, the expression is re-evaluated for each n, leading to a different list.

answered Oct 27, 2008 at 15:07
3
  • Just a small addition to the nice answer here: it's evident that you're dealing with same object if you do id(lst[0][0]) and id(lst[1][0]) or even id(lst[0]) and id(lst[1]) Commented May 17, 2017 at 7:08
  • Doesn't explain why modifying a 1d list causes a copy while a 2d list doesn't cause any copy Commented Jun 10, 2022 at 17:55
  • 1
    @JobHunter69 neither does copying; it's all an illusion. With a 1d list of immutable objects such as numbers or strings, you can't change those list elements; you can only replace them with new values. It looks like you have a copy even though you don't. The 2d list is actually a list of lists, and you can easily change those inner lists. Commented Nov 4, 2022 at 18:40
49
[[1] * 4] * 3

or even:

[[1, 1, 1, 1]] * 3

Creates a list that references the internal [1,1,1,1] 3 times - not three copies of the inner list, so any time you modify the list (in any position), you'll see the change three times.

It's the same as this example:

>>> inner = [1,1,1,1]
>>> outer = [inner]*3
>>> outer
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> inner[0] = 5
>>> outer
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]

where it's probably a little less surprising.

Dimitris Fasarakis Hilliard
162k35 gold badges282 silver badges265 bronze badges
answered Oct 27, 2008 at 15:02
1
  • 3
    You can use the "is" operator to discover this. ls[0] is ls[1] returns True. Commented Oct 27, 2008 at 15:03
13

my_list = [[1]*4] * 3 creates one list object [1,1,1,1] in memory and copies its reference 3 times over. This is equivalent to obj = [1,1,1,1]; my_list = [obj]*3. Any modification to obj will be reflected at three places, wherever obj is referenced in the list. The right statement would be:

my_list = [[1]*4 for _ in range(3)]

or

my_list = [[1 for __ in range(4)] for _ in range(3)]

Important thing to note here is that the * operator is mostly used to create a list of literals. Although 1 is immutable, obj = [1]*4 will still create a list of 1 repeated 4 times over to form [1,1,1,1]. But if any reference to an immutable object is made, the object is overwritten with a new one.

This means if we do obj[1] = 42, then obj will become [1,42,1,1] not (削除) [42,42,42,42] (削除ここまで) as some may assume. This can also be verified:

>>> my_list = [1]*4
>>> my_list
[1, 1, 1, 1]
>>> id(my_list[0])
4522139440
>>> id(my_list[1]) # Same as my_list[0]
4522139440

>>> my_list[1] = 42 # Since my_list[1] is immutable, this operation overwrites my_list[1] with a new object changing its id.
>>> my_list
[1, 42, 1, 1]
>>> id(my_list[0])
4522139440
>>> id(my_list[1]) # id changed
4522140752
>>> id(my_list[2]) # id still same as my_list[0], still referring to value `1`.
4522139440
answered Apr 6, 2017 at 5:36
1
  • 3
    It's not about literals. obj[2] = 42 replaces the reference at index 2, as opposed to mutating the object referenced by that index, which is what myList[2][0] = ... does (myList[2] is a list, and the assigment alters the reference at index 0 in tha list). Of course, integers are not mutable, but plenty of object types are. And note that the [....] list display notation is also a form of literal syntax! Don't confuse compound (such as lists) and scalar objects (such as integers), with mutable vs. immutable objects. Commented Jul 25, 2018 at 15:52
10

Alongside the accepted answer that explained the problem correctly, instead of creating a list with duplicated elements using following code:

[[1]*4 for _ in range(3)]

Also, you can use itertools.repeat() to create an iterator object of repeated elements:

>>> a = list(repeat(1,4))
[1, 1, 1, 1]
>>> a[0] = 5
>>> a
[5, 1, 1, 1]

P.S. If you're using NumPy and you only want to create an array of ones or zeroes you can use np.ones and np.zeros and/or for other numbers use np.repeat:

>>> import numpy as np
>>> np.ones(4)
array([1., 1., 1., 1.])
>>> np.ones((4, 2))
array([[1., 1.],
 [1., 1.],
 [1., 1.],
 [1., 1.]])
>>> np.zeros((4, 2))
array([[0., 0.],
 [0., 0.],
 [0., 0.],
 [0., 0.]])
>>> np.repeat([7], 10)
array([7, 7, 7, 7, 7, 7, 7, 7, 7, 7])
answered Jun 17, 2015 at 17:08
9

Python containers contain references to other objects. See this example:

>>> a = []
>>> b = [a]
>>> b
[[]]
>>> a.append(1)
>>> b
[[1]]

In this b is a list that contains one item that is a reference to list a. The list a is mutable.

The multiplication of a list by an integer is equivalent to adding the list to itself multiple times (see common sequence operations). So continuing with the example:

>>> c = b + b
>>> c
[[1], [1]]
>>>
>>> a[0] = 2
>>> c
[[2], [2]]

We can see that the list c now contains two references to list a which is equivalent to c = b * 2.

Python FAQ also contains explanation of this behavior: How do I create a multidimensional list?

answered Apr 6, 2016 at 13:40
7

I am adding my answer to explain the same diagrammatically.

The way you created the 2D, creates a shallow list

arr = [[0]*cols]*row

Instead, if you want to update the elements of the list, you should use

rows, cols = (5, 5) 
arr = [[0 for i in range(cols)] for j in range(rows)] 

Explanation:

One can create a list using:

arr = [0]*N 

or

arr = [0 for i in range(N)] 

In the first case all the indices of the array point to the same integer object

enter image description here

and when you assign a value to a particular index, a new int object is created, for example arr[4] = 5 creates

enter image description here

Now let us see what happens when we create a list of list, in this case, all the elements of our top list will point to the same list

enter image description here

And if you update the value of any index a new int object will be created. But since all the top-level list indexes are pointing at the same list, all the rows will look the same. And you will get the feeling that updating an element is updating all the elements in that column.

enter image description here

Credits: Thanks to Pranav Devarakonda for the easy explanation here

mkrieger1
24k7 gold badges67 silver badges83 bronze badges
answered Jun 21, 2020 at 11:34
1
5

Let's rewrite your code in the following way:

x = 1
y = [x]
z = y * 4
my_list = [z] * 3

Then having this, run the following code to make everything more clear. What the code does is basically print the ids of the obtained objects, which

Return[s] the "identity" of an object

and will help us identify them and analyse what happens:

print("my_list:")
for i, sub_list in enumerate(my_list):
 print("\t[{}]: {}".format(i, id(sub_list)))
 for j, elem in enumerate(sub_list):
 print("\t\t[{}]: {}".format(j, id(elem)))

And you will get the following output:

x: 1
y: [1]
z: [1, 1, 1, 1]
my_list:
 [0]: 4300763792
 [0]: 4298171528
 [1]: 4298171528
 [2]: 4298171528
 [3]: 4298171528
 [1]: 4300763792
 [0]: 4298171528
 [1]: 4298171528
 [2]: 4298171528
 [3]: 4298171528
 [2]: 4300763792
 [0]: 4298171528
 [1]: 4298171528
 [2]: 4298171528
 [3]: 4298171528

So now let's go step-by-step. You have x which is 1, and a single element list y containing x. Your first step is y * 4 which will get you a new list z, which is basically [x, x, x, x], i.e. it creates a new list which will have 4 elements, which are references to the initial x object. The next step is pretty similar. You basically do z * 3, which is [[x, x, x, x]] * 3 and returns [[x, x, x, x], [x, x, x, x], [x, x, x, x]], for the same reason as for the first step.

answered Jun 10, 2015 at 14:38
0
5

In simple words this is happening because in python everything works by reference, so when you create a list of list that way you basically end up with such problems.

To solve your issue you can do either one of them:

  1. Use numpy array; documentation for numpy.empty
  2. Append the list as you get to a list.
  3. You can also use dictionary if you want
wjandrea
33.5k10 gold badges69 silver badges104 bronze badges
answered Jun 14, 2016 at 6:36
4

Everyone is explaining what is happening. I'll suggest one way to solve it:

my_list = [[1 for i in range(4)] for j in range(3)]
my_list[0][0] = 5
print(my_list)

And then you get:

[[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
answered Apr 24, 2016 at 13:31
1
  • This doesn't work with anything other than primitives / immutable. Commented Jun 10, 2024 at 13:56
4

@spelchekr from Python list multiplication: [[...]]*3 makes 3 lists which mirror each other when modified and I had the same question about "Why does only the outer *3 create more references while the inner one doesn't? Why isn't it all 1s?"

li = [0] * 3
print([id(v) for v in li]) # [140724141863728, 140724141863728, 140724141863728]
li[0] = 1
print([id(v) for v in li]) # [140724141863760, 140724141863728, 140724141863728]
print(id(0)) # 140724141863728
print(id(1)) # 140724141863760
print(li) # [1, 0, 0]
ma = [[0]*3] * 3 # mainly discuss inner & outer *3 here
print([id(li) for li in ma]) # [1987013355080, 1987013355080, 1987013355080]
ma[0][0] = 1
print([id(li) for li in ma]) # [1987013355080, 1987013355080, 1987013355080]
print(ma) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]

Here is my explanation after trying the code above:

  • The inner *3 also creates references, but its references are immutable, something like [&0, &0, &0], then when you change li[0], you can't change any underlying reference of const int 0, so you can just change the reference address into the new one &1;
  • while ma = [&li, &li, &li] and li is mutable, so when you call ma[0][0] = 1, ma[0][0] is equal to &li[0], so all the &li instances will change its 1st address into &1.
answered Aug 9, 2019 at 8:37
3

Trying to explain it more descriptively,

Operation 1:

x = [[0, 0], [0, 0]]
print(type(x)) # <class 'list'>
print(x) # [[0, 0], [0, 0]]
x[0][0] = 1
print(x) # [[1, 0], [0, 0]]

Operation 2:

y = [[0] * 2] * 2
print(type(y)) # <class 'list'>
print(y) # [[0, 0], [0, 0]]
y[0][0] = 1
print(y) # [[1, 0], [1, 0]]

Noticed why doesn't modifying the first element of the first list didn't modify the second element of each list? That's because [0] * 2 really is a list of two numbers, and a reference to 0 cannot be modified.

If you want to create clone copies, try Operation 3:

import copy
y = [0] * 2 
print(y) # [0, 0]
y = [y, copy.deepcopy(y)] 
print(y) # [[0, 0], [0, 0]]
y[0][0] = 1
print(y) # [[1, 0], [0, 0]]

another interesting way to create clone copies, Operation 4:

import copy
y = [0] * 2
print(y) # [0, 0]
y = [copy.deepcopy(y) for num in range(1,5)]
print(y) # [[0, 0], [0, 0], [0, 0], [0, 0]]
y[0][0] = 5
print(y) # [[5, 0], [0, 0], [0, 0], [0, 0]]
answered Aug 10, 2016 at 7:09
2

By using the inbuilt list function you can do like this

a
out:[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
#Displaying the list
a.remove(a[0])
out:[[1, 1, 1, 1], [1, 1, 1, 1]]
# Removed the first element of the list in which you want altered number
a.append([5,1,1,1])
out:[[1, 1, 1, 1], [1, 1, 1, 1], [5, 1, 1, 1]]
# append the element in the list but the appended element as you can see is appended in last but you want that in starting
a.reverse()
out:[[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
#So at last reverse the whole list to get the desired list
answered Jul 15, 2016 at 13:48
1
  • 2
    Note, fourth step can be dropped if you make second step: a.insert(0,[5,1,1,1]) Commented Oct 19, 2018 at 5:29
1

From official documentation:

Note that items in the sequence s are not copied; they are referenced multiple times. This often haunts new Python programmers; consider::

 >>> lists = [[]] * 3
 >>> lists
 [[], [], []]
 >>> lists[0].append(3)
 >>> lists
 [[3], [3], [3]]

What has happened is that [[]] is a one-element list containing an empty list, so all three elements of [[]] * 3 are references to this single empty list. Modifying any of the elements of lists modifies this single list. You can create a list of different lists this way::

 >>> lists = [[] for i in range(3)]
 >>> lists[0].append(3)
 >>> lists[1].append(5)
 >>> lists[2].append(7)
 >>> lists
 [[3], [5], [7]]
answered Feb 17, 2024 at 12:38
0

I arrived here because I was looking to see how I could nest an arbitrary number of lists. There are a lot of explanations and specific examples above, but you can generalize N dimensional list of lists of lists of ... with the following recursive function:

import copy
def list_ndim(dim, el=None, init=None):
 if init is None:
 init = el
 if len(dim)> 1:
 return list_ndim(dim[0:-1], None, [copy.copy(init) for x in range(dim[-1])])
 return [copy.deepcopy(init) for x in range(dim[0])]

You make your first call to the function like this:

dim = (3,5,2)
el = 1.0
l = list_ndim(dim, el)

where (3,5,2) is a tuple of the dimensions of the structure (similar to numpy shape argument), and 1.0 is the element you want the structure to be initialized with (works with None as well). Note that the init argument is only provided by the recursive call to carry forward the nested child lists

output of above:

[[[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]]]

set specific elements:

l[1][3][1] = 56
l[2][2][0] = 36.0+0.0j
l[0][1][0] = 'abc'

resulting output:

[[[1.0, 1.0], ['abc', 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 56.0], [1.0, 1.0]],
 [[1.0, 1.0], [1.0, 1.0], [(36+0j), 1.0], [1.0, 1.0], [1.0, 1.0]]]

the non-typed nature of lists is demonstrated above

answered Oct 22, 2020 at 19:57
0

While the original question constructed the sublists with the multiplication operator, I'll add an example that uses the same list for the sublists. Adding this answer for completeness as this question is often used as a canonical for the issue

node_count = 4
colors = [0,1,2,3]
sol_dict = {node:colors for node in range(0,node_count)}

The list in each dictionary value is the same object, trying to change one of the dictionaries values will be seen in all.

>>> sol_dict
{0: [0, 1, 2, 3], 1: [0, 1, 2, 3], 2: [0, 1, 2, 3], 3: [0, 1, 2, 3]}
>>> [v is colors for v in sol_dict.values()]
[True, True, True, True]
>>> sol_dict[0].remove(1)
>>> sol_dict
{0: [0, 2, 3], 1: [0, 2, 3], 2: [0, 2, 3], 3: [0, 2, 3]}

The correct way to construct the dictionary would be to use a copy of the list for each value.

>>> colors = [0,1,2,3]
>>> sol_dict = {node:colors[:] for node in range(0,node_count)}
>>> sol_dict
{0: [0, 1, 2, 3], 1: [0, 1, 2, 3], 2: [0, 1, 2, 3], 3: [0, 1, 2, 3]}
>>> sol_dict[0].remove(1)
>>> sol_dict
{0: [0, 2, 3], 1: [0, 1, 2, 3], 2: [0, 1, 2, 3], 3: [0, 1, 2, 3]}
community wiki

0

Note that items in the sequence are not copied; they are referenced multiple times. This often haunts new Python programmers; consider:

>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]

What has happened is that [[]] is a one-element list containing an empty list, so all three elements of [[]] * 3 are references to this single empty list. Modifying any of the elements of lists modifies this single list.

Another example to explain this is using multi-dimensional arrays.

You probably tried to make a multidimensional array like this:

>>> A = [[None] * 2] * 3

This looks correct if you print it:

>>> A
[[None, None], [None, None], [None, None]]

But when you assign a value, it shows up in multiple places:

>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]

The reason is that replicating a list with * doesn’t create copies, it only creates references to the existing objects. The 3 creates a list containing 3 references to the same list of length two. Changes to one row will show in all rows, which is almost certainly not what you want.

answered Nov 22, 2020 at 19:45
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.