12

I just randomly observed the following in Python and am curious to know the reason why this evaluates to False:

list(list()) == [[]]

Interestingly if you rearrange the syntax in the following ways, the first way evaluates as False, but the second as True:

list([]) == [[]]
[list()] == [[]]

What is going on under the hood here?

William Miller
  • 9,839
  • 3
  • 25
  • 46
Toby Petty
  • 4,431
  • 1
  • 17
  • 29

4 Answers4

12

From the the Python 2 documentation on the list constructor

class list([iterable])

Return a list whose items are the same and in the same order as iterable’s items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to iterable[:]. For instance, list('abc') returns ['a', 'b', 'c'] and list( (1, 2, 3) ) returns [1, 2, 3]. If no argument is given, returns a new empty list, [].

When you pass a list to list() it returns a copy, not a nested list, whereas [[]] creates an empty nested list - or rather a list containing a single element which is itself an empty list.


Note   -   This is notably absent from the corresponding Python 3 documentation, but it holds true for Python 3 regardless.

William Miller
  • 9,839
  • 3
  • 25
  • 46
9

list does not construct a list that contains its argument; it constructs a list whose elements are contained in its argument. list([]) does not return [[]]; it returns []. Thus, list(list()) == list([]) == [].

chepner
  • 497,756
  • 71
  • 530
  • 681
6

list(...) constructor is not doing the same thing as the list literal [...]. The constructor takes any iterable and makes a list out of its items

>>> list((1, 2, 3))
[1, 2, 3]
>>> list("foo")
['f', 'o', 'o']
>>> list(list())

whereas a list literal defines a list with exactly the enumerated items

>>> [(1, 2, 3)]
[(1, 2, 3)]
>>> ["foo"]
['foo']
>>> [[]]
[[]]

Note that when called without any arguments, list() produces the same result as [].

Sergei Lebedev
  • 2,659
  • 20
  • 23
3

When you do list(list()) you are creating a list and convert it to a list on the fly. Therefore, you end up with a single empty list, not a nested list.

mcsoini
  • 6,280
  • 2
  • 15
  • 38
  • 1
    In other words the `list` constructor takes an iterable (producing an empty list if non is supplied) so `list(list())` = `list([])` = `list()` = `[]` – modesitt Nov 21 '19 at 20:33