1

It is possible to go about creating lists like this:

l = list()

l.append(1)

however the most common method is to create a list like this:

l = [1]

My question is simple in the concept but probably extremely complicated in the answer but how is it that the list is created with a notation outside the usual class notation?

I have looked through the source code at https://github.com/python/cpython/blob/master/Objects/listobject.c and cant find where it defines the list notation [].

I am not asking about the difference between [] and list() - I am asking why you can use [] at all. How is it possible that this object is created differently from other objects?

yrrah2
  • 61
  • 4
  • `list` is the name of the class, and also a builtin – Jean-François Fabre Apr 01 '19 at 11:44
  • yes but I want to know where in the python source code that it is defined to be created with the square brackets – yrrah2 Apr 01 '19 at 11:45
  • 1
    related: https://stackoverflow.com/questions/33716401/whats-the-difference-between-list-and – Jean-François Fabre Apr 01 '19 at 11:45
  • im more asking about how one would go about defining a new data structure using notation that is different from the regular class notation – yrrah2 Apr 01 '19 at 11:48
  • Possible duplicate of [What's the difference between list() and \[\]](https://stackoverflow.com/questions/33716401/whats-the-difference-between-list-and) – Ma0 Apr 01 '19 at 11:48
  • It's part of the grammar: `atom: ... | '[' [testlist_comp] '] | ...`; it's not something you can define yourself *in* Python. – chepner Apr 01 '19 at 11:49
  • I think the definition of this notation should be somewhere in the parser: when it sees this particular syntax, it generates code to initialise a list. – ForceBru Apr 01 '19 at 11:50

2 Answers2

3

The list literal [...] is defined by the grammar, the same as keywords like if and while:

atom: ... | '[' [testlist_comp] '] | ...

When the code generator encounters a list literal in the AST, it generates a specific byte code to create a list:

>>> import dis
>>> dis.dis('[]')
  1           0 BUILD_LIST               0
              2 RETURN_VALUE

whereas a call to list is handled like any other callable:

>>> dis.dis('list()')
  1           0 LOAD_NAME                0 (list)
              2 CALL_FUNCTION            0
              4 RETURN_VALUE

For non-empty lists, the expressions in the literal are added to the stack for BUILD_LIST to use:

>>> dis.dis('list([1,2])')
  1           0 LOAD_NAME                0 (list)
              2 LOAD_CONST               0 (1)
              4 LOAD_CONST               1 (2)
              6 BUILD_LIST               2
              8 CALL_FUNCTION            1
             10 RETURN_VALUE

A call like list([1,2]) necessarily uses BUILD_LIST first to create a list before passing that to list as an argument.

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

[1] is a list-literal - it implicitly creates the list() with 1 in it (stores it in the heap). I'm sure you can find this if you dig around in the code-base a bit more.

rdas
  • 20,604
  • 6
  • 33
  • 46