Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do the list function and list literals act differently?

Tags:

python

list

I was trying to create a list with n empty lists inside of it, but faced an interesting situation.

Firstly I tried the following:

>>> n = 3
>>> list([]) * n
[]

It creates an empty list.

After that I tried the following line, which creates an empty list, too:

>>> list(list()) * n
[]

But when I try the same with literals,

>>> [[]] * n 
[[], [], []]

it gives the correct output. Can someone explain why?

like image 618
Sekomer Avatar asked Dec 22 '22 15:12

Sekomer


1 Answers

list(...) is not interchangeable with [...]. You can wrap square brackets around things to get nested lists, but wrapping things in list() doesn't have the same effect.

  • When you write [[]] you get a list with a single element. That element is [].

  • When you write list([]) the list constructor takes an iterable and creates a list with the same elements. If you wrote list(['foo', 'bar']) the result would be ['foo', 'bar']. Writing list([]) yields [].

    This form is more useful when you pass iterables that aren't lists. Other examples:

    list('abc') == ['a', 'b', 'c']         # strings are iterables over their characters
    list(('foo', 'bar')) == ['foo', 'bar'] # tuple
    list({'foo', 'bar'}) == ['foo', 'bar'] # set; could get ['bar', 'foo'] instead
    
  • list(list()) is equivalent to list([]). And we've seen that's in turn equivalent to [].

Stay away from [[]] * n when creating a multidimensional list. It will create a list with n references to the same list object and will bite you when you try to modify the internal lists. It's a common mistake that everyone makes. Use this instead, which will create a separate empty list for each slot:

[[] for i in range(n)]

Further reading:

  • How to create a multi-dimensional list
  • List of lists changes reflected across sublists unexpectedly
like image 163
John Kugelman Avatar answered Dec 28 '22 09:12

John Kugelman