Esta é a desmontagem de uma compreensão de lista em python 3.10:
Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>>
>>> dis.dis("[True for _ in ()]")
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x7fea68e0dc60, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_CONST 2 (())
8 GET_ITER
10 CALL_FUNCTION 1
12 RETURN_VALUE
Disassembly of <code object <listcomp> at 0x7fea68e0dc60, file "<dis>", line 1>:
1 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 4 (to 14)
6 STORE_FAST 1 (_)
8 LOAD_CONST 0 (True)
10 LIST_APPEND 2
12 JUMP_ABSOLUTE 2 (to 4)
>> 14 RETURN_VALUE
Pelo que entendi ele cria um objeto de código chamado listcomp
que faz a iteração real e retorna a lista de resultados, e o chama imediatamente. Não consigo entender a necessidade de criar uma função separada para executar este trabalho. Isso é um tipo de truque de otimização?
A principal lógica de criação de uma função é isolar a variável de iteração da compreensão peps.python.org . Criando uma função:
Mas é ineficiente em tempo de execução . Por causa disso, python-3.12 implementou uma otimização chamada compreensão inlining(PEP 709) peps.python.org que não criará mais um objeto de código separado peps.python.org .
Aqui está a saída para o mesmo código desmontado com python-3.12 (como você pode ver, não há mais um
MAKE_FUNCTION
opcode)