Sou um programador iniciante e fiz um curso de C e obtive (o que acredito e espero ser) uma compreensão muito boa de como diferentes funções e tipos de dados alocam memória de maneira diferente.
Então, com isso em mente, alguém poderia explicar como range()
o Python usa memória, por favor?
Eu sei range()
que no Python 2 criaria uma lista de valores, então é bastante simples de entender, mas no Python 3, continuo vendo pessoas dizerem que "cria um novo objeto" ou cria um "objeto iterador", mas o que o computador faz internamente em relação à memória?
Além disso, pelo que entendi, os loops for funcionam da mesma maneira que os loops for-each funcionam em Java, então como uma função como for n in range(6)
funciona se não está iterando em uma lista de 6 números de 0 a 5?
Só para deixar claro, sei que, como iniciante, o uso de memória não deve ser uma preocupação, mas gosto de saber como as coisas funcionam nos bastidores.
O objeto Python 3
range()
não aloca memória ao criá-lo; é um objeto de sequência . Tudo o que contém são os valores de início, parada e passo.Ele ‘gera’ números sob demanda, neste caso, a ‘demanda’ é o loop
for n in range(6):
. À medida que você 'itera' sobre o objeto, o próximo número inteiro é calculado a cada iteração.O
range
objeto retorna um iterador quando chamado__iter__()
. Ofor
loop chama automaticamente esta função.Podemos obter o próximo valor chamando
next()
-o. Por exemplo:O loop para automaticamente quando
next()
aumentaStopIteration
.Uma possível implementação seria como:
Nota: Esta não é a implementação real do
range
; O verdadeiro é muito mais complicado que isso.A função acima não aloca nenhuma memória, mas pode ser usada como
range()
.Você diz: "Eu sei que range() no Python 2 criaria uma lista de valores" - não acho que isso seja totalmente verdade, mas não importa muito, pois você provavelmente não deveria usar o Python 2 neste estágio. O que é importante perceber é que Python tem muitas implementações diferentes, que não precisam fazer a mesma coisa "nos bastidores", elas só precisam ser implementações corretas da linguagem.
Como funciona para implementações comuns como CPython é explicado na documentação: https://docs.python.org/3/library/stdtypes.html#typesseq-range
Especificamente: "A vantagem do tipo de intervalo sobre uma lista ou tupla regular é que um objeto de intervalo sempre ocupará a mesma (pequena) quantidade de memória, não importa o tamanho do intervalo que ele representa (já que armazena apenas o início, parada e valores de etapas, calculando itens individuais e subintervalos conforme necessário)."
Você também diz: "Eu simplesmente gosto de saber como as coisas funcionam nos bastidores" - o objetivo de usar uma linguagem de ordem superior geralmente é que você não precisa saber exatamente o que está acontecendo nos bastidores. Deve ser suficiente saber que
range()
é uma maneira muito eficiente de obter acesso a um intervalo de valores enquanto ocupa pouco espaço de memória e tem bom desempenho, definitivamente quando comparado à alternativa como criar uma lista ou escrever um gerador em Python para fazer o mesmo."como funciona uma função como for n in range(6):" - isso não é uma função , mas funciona porque um intervalo é iterável e
for
pode, portanto, iterar sobre seu conteúdo do início ao fim. Você poderia substituirrange(6)
por qualquer iterável efor
funcionaria exatamente da mesma forma (exceto que,n
é claro, assumiria os valores relevantes do iterável.