(válido somente para Python 2.x)
A função range()
Em Python, é muito comum usarmos a seguinte estrutura para realizar uma repetição baseada em um contador:
for i in range(0, 10):
print i,
A função range(x, y) gera uma lista de números inteiros de x até y (sem incluir o segundo). Assim, range(0, 10), gera a seguinte lista:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Desse modo, a variável i é iterada sobre essa lista, através da estrutura de repetição for. O trecho de código:
for i in range(0, 10):
print i,
pode ser lido como:
"Para cada elemento na lista [0,1,2,3,4,5,6,7,8,9], imprima tal elemento"
Usar range() ou xrange()? Eis a questão…
É comum ouvirmos ou lermos algum desenvolvedor Python aconselhando a utilização da função xrange() ao invés da função range(), por questões de desempenho. Mas o que é essa tal de xrange()?
A xrange() nada mais é do que uma função que pode, em muitos casos (não sempre), substituir o uso da função range(), fornecendo ainda melhor desempenho. Veja o código abaixo:
for i in xrange(0, 10): print i,
O resultado dessa execução é o mesmo de quando utilizamos a função range(), porém, por gerar um elemento de cada vez, o código que utiliza a função xrange() apresenta um desempenho superior.
Quando executamos:
for i in range(0, 1000000000):
pass
A função range() irá imediatamente gerar uma lista contendo um bilhão de inteiros e alocar essa lista na memória. Uma lista contendo um bilhão de inteiros é capaz de encher a memória de um computador pessoal.
Já com a função xrange(), ao executarmos:
for i in xrange(0, 1000000000):
pass
Cada um dos inteiros (dos 1 bilhão) será gerado de uma vez, economizando memória e tempo de startup.
Vamos então testar o desempenho usando o módulo timeit().
A hora da verdade
junior@qwerty:~ $ python -m timeit "for i in xrange(10000000): pass" 10 loops, best of 3: 246 msec per loop junior@qwerty:~-$ python -m timeit "for i in range(10000000): pass" 10 loops, best of 3: 342 msec per loop
Como podemos ver, o loop que utiliza a função xrange() foi quase 100 milisegundos mais rápido do que o loop que utiliza a função range(). Além disso, se fizermos uma análise de consumo de memória, veremos que a o código que utiliza a função range() utiliza uma quantidade de memória muito maior, pois gera a lista inteira antes de executar a iteração do for.
Então nunca mais vou usar o range(), certo?
Errado! Existe uma diferença fundamental entre as duas funções: a função xrange() não gera uma lista. Isso torna inviável, por exemplo, o slicing e a gravação de seu resultado como uma lista em uma variável. Vejamos:
>>> x = range(0, 10) >>> print x [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> y = xrange(0, 10) >>> print y xrange(10)
Ou seja, apesar de nos fornecer um desempenho superior ao desempenho obtido com a range(), a função xrange() não substitui a anterior em todos os seus casos.
meu amigo, me desculpe mas eu tenho que discordar! , no ultimo caso que você disse que xrange() não substitui range() , posso substitui-lo como no exempo:
s = list(xrange(10))
então “print s” resultaria em:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Poder até pode, assim como você poderia criar um objeto inteiro da seguinte forma:
😛
Por que converter um objeto
xrangeem uma lista se eu posso obter uma lista usando orangedireto?Valeu pelo comentário!
Mas por que faria isso? Por que não fazer simplesmente range(10)? range já gera a lista…
se você usar o metodo que eu apresentei, usando o timeit, poderá ver a diferença de performance.
Pois é, aí depende do tamanho da lista em questão.
Essa era minha duvida para mim era a mesma coisa
Parabéns pelo artigo.
Foi de grande utilidade pra mim.
Grande abraço!
Muito explicativo! Muito obrigada!