pythonlistnested-listsmutable

Why does this code for initializing a list of lists apparently link the lists together?


I intend to initialize a list of list with length of n.

x = [[]] * n

However, this somehow links the lists together.

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

I expect to have something like:

[[], [0], []]

Any ideas?


Solution

  • The problem is that they're all the same exact list in memory. When you use the [x]*n syntax, what you get is a list of n many x objects, but they're all references to the same object. They're not distinct instances, rather, just n references to the same instance.

    To make a list of 3 different lists, do this:

    x = [[] for i in range(3)]
    

    This gives you 3 separate instances of [], which is what you want

    [[]]*n is similar to

    l = []
    x = []
    for i in range(n):
        x.append(l)
    

    While [[] for i in range(3)] is similar to:

    x = []
    for i in range(n):
        x.append([])   # appending a new list!
    

    In [20]: x = [[]] * 4
    
    In [21]: [id(i) for i in x]
    Out[21]: [164363948, 164363948, 164363948, 164363948] # same id()'s for each list,i.e same object
    
    
    In [22]: x=[[] for i in range(4)]
    
    In [23]: [id(i) for i in x]
    Out[23]: [164382060, 164364140, 164363628, 164381292] #different id(), i.e unique objects this time