0

Whenever I come to define an empty list. Which is best practice? Is one better than the other? Are they identical?

mylist = list()

or?

mylist = []

My question is also relevant to:

# int() && 0
# str() && ""
# float() && 0.0
# etc.

But just in case there's a difference. I am only interested in the answer for lists.

blhsing
  • 91,368
  • 6
  • 71
  • 106
Meeky333
  • 75
  • 6

1 Answers1

0

EDIT: I actually ran that again, and [] turned out to be faster. Added the new scores.

I prefer mylist=[] for readability, but mylist = list() also works. In terms of performance:

>>> python -m timeit 'mylist=[]'
10000000 loops, best of 3: 0.0229 usec per loop
>>> python -m timeit 'mylist=list()'
10000000 loops, best of 3: 0.105 usec per loop
Péter Leéh
  • 2,069
  • 2
  • 10
  • 23
  • 1
    `list()` is probably a bit slower in real life. In your timing, the compiler might have the benefit of noting that `list` could not have been assigned any other value, and so optimized to `mylist = []`. In real life, the compiler would likely have to perform the global name lookup and call the type, rather than simply assume that `list() == []`. – chepner Nov 19 '19 at 17:10
  • @chepner pretty sure that isn't happening. There is no way for the compiler to know that, for example, calling `list` could modify `list`! – juanpa.arrivillaga Nov 19 '19 at 17:21
  • @juanpa.arrivillaga With a very small, constrained source, it can. Compare `python -m timeit -s 'listb = list' 'mylist = listb()'` with `python -m timeit -s 'listb = list' 'mylist = []'`; in my tests, the former is 3 times slower. – chepner Nov 19 '19 at 17:29
  • (I suspect that if the peephole optimizer sees that `list` is bound in the built-in scope, it can determine it is safe to replace `list()` with `[]`.) – chepner Nov 19 '19 at 17:32
  • @chepner I'm not sure what you think that demonstrates. In any case, I am pretty sure there is no such optimization done by the Python compiler, the peephole optimizer is limited to pretty basic things. – juanpa.arrivillaga Nov 19 '19 at 17:32
  • @chepner so note, `python -m timeit -s 'listb = list' 'mylist = list()` is slower than `python -m timeit -s 'listb = list' 'mylist = listb()` which is slower than `python -m timeit -s 'listb = list' 'mylist = []`, which is exactly what we would expect if the interpreter were simply acting stupidly, but optimizing the building of the literal by supporting it at the byte-code level – juanpa.arrivillaga Nov 19 '19 at 17:34
  • Since I claim that Python optimizes away the name lookup in `mylist = list()` alone, my point was to generate a test that forces a name lookup. – chepner Nov 19 '19 at 17:36
  • @chepner well, you can use `dis` to see that the compiler is definitely not doing this. If the peep-hole optimizer were able to figure this out, you'd see the same bytecode generated for `mylist=list()` and `mylist = []`. And you do not. – juanpa.arrivillaga Nov 19 '19 at 17:38
  • I don't think `dis` is doing the same optimization, since it's not actually running anything. – chepner Nov 19 '19 at 17:40
  • @chepner dude, dis is telling you *exactly* what the interpreter sees *before* it runs anything, and the bytecode is what gets executed. There is no other opportunity for it to optimize anything at that point, what's in the bytecode is what gets executed. Of course, this is about CPython, a JITed python implementation would be another story. – juanpa.arrivillaga Nov 19 '19 at 17:51
  • So, just like Péter, I reran the test, and likewise do not see `[]` and `list()` taking the same amount of time now. I'm not sure what I was doing wrong. – chepner Nov 19 '19 at 17:57