Home > Mobile >  [] and list() and 'int' object is not iterable in Python
[] and list() and 'int' object is not iterable in Python

Time:01-13

Let's say I have an integer I want to make a list.

This works

[1]

However, this results in 'int' object is not iterable

list(1)

What is the difference between [] and list() and when is it appropriate to use each?

CodePudding user response:

They're entirely different things; list is a built-in and [] are operators that can be used for, for example, either list comprehension or for list initialisation (which is what you're doing), but also for accessing certain indices in containers, etc. So you're kind of comparing apples and oranges.

Between list with generator expressions and list comprehension, the latter is actually faster:

$ python3 -m timeit '[_ for _ in range(1000)]'
10000 loops, best of 5: 29.4 usec per loop
$ python3 -m timeit 'list(_ for _ in range(1000))'
5000 loops, best of 5: 42.9 usec per loop

If we disassemble into bytecode we get:

  • for list comprehension
>>> dis.dis('[_ for _ in range(10)]')
  1           0 LOAD_CONST               0 (<code object <listcomp> at 0x10d0647c0, file "<dis>", line 1>)
              2 LOAD_CONST               1 ('<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_NAME                0 (range)
              8 LOAD_CONST               2 (10)
             10 CALL_FUNCTION            1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x10d0647c0, file "<dis>", line 1>:
  1           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                 8 (to 14)
              6 STORE_FAST               1 (_)
              8 LOAD_FAST                1 (_)
             10 LIST_APPEND              2
             12 JUMP_ABSOLUTE            4
        >>   14 RETURN_VALUE
  • for list plus a generator expression
>>> dis.dis('list(_ for _ in range(10))')
  1           0 LOAD_NAME                0 (list)
              2 LOAD_CONST               0 (<code object <genexpr> at 0x10d0647c0, file "<dis>", line 1>)
              4 LOAD_CONST               1 ('<genexpr>')
              6 MAKE_FUNCTION            0
              8 LOAD_NAME                1 (range)
             10 LOAD_CONST               2 (10)
             12 CALL_FUNCTION            1
             14 GET_ITER
             16 CALL_FUNCTION            1
             18 CALL_FUNCTION            1
             20 RETURN_VALUE

Disassembly of <code object <genexpr> at 0x10d0647c0, file "<dis>", line 1>:
  1           0 LOAD_FAST                0 (.0)
        >>    2 FOR_ITER                10 (to 14)
              4 STORE_FAST               1 (_)
              6 LOAD_FAST                1 (_)
              8 YIELD_VALUE
             10 POP_TOP
             12 JUMP_ABSOLUTE            2
        >>   14 LOAD_CONST               0 (None)
             16 RETURN_VALUE

So outside of having to look up the name (list, LOAD_NAME), it seems to be mostly down to internal design; that the generator expression is popping indicates a stack.


Compare this with what you were doing:

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

First one builds a list, while the second is (after looking up the name) trying to call the function list (which actually is a mutable sequence type class).

CodePudding user response:

list() takes an Iterable (for instance: instances of set, dict, tuple) as argument, [] takes an explicit listing of the elements or a comprehension.

CodePudding user response:

I don't think that you can use an integer with that

  •  Tags:  
  • Related