Pergunta

Aparentemente xrange é mais rápido, mas não tenho idéia por que é mais rápido (e nenhuma prova além do anedótico tão longe que é mais rápido) ou o que, além de que é diferente sobre

for i in range(0, 20):
for i in xrange(0, 20):
Foi útil?

Solução

gama cria uma lista, por isso, se você fizer range(1, 10000000) ele cria uma lista na memória com elementos 9999999.

xrange é um objecto sequência que avalia preguiça.

Deve-se acrescentar de @ dica de Thiago, que em python3, gama faz o equivalente de python é xrange

Outras dicas

gama cria uma lista, por isso, se você fizer range(1, 10000000) ele cria uma lista na memória com elementos 9999999.

xrange é um gerador, por isso é um objecto sequência é um que avalia preguiça.

Isso é verdade, mas em Python 3, .range() será implementado pela .xrange() Python 2. Se você precisa realmente gerar a lista, você precisará fazer:

list(range(1,100))

Lembre-se, use o módulo timeit de teste que de pequenos trechos de código é mais rápido!

$ python -m timeit 'for i in range(1000000):' ' pass'
10 loops, best of 3: 90.5 msec per loop
$ python -m timeit 'for i in xrange(1000000):' ' pass'
10 loops, best of 3: 51.1 msec per loop

Pessoalmente, eu sempre uso .range(), a menos que eu estava lidando com realmente listas enormes - como você pode ver, o tempo-sábio, para uma lista de um milhão de entradas, a sobrecarga extra é de apenas 0,04 segundos. E, como Corey salienta, em Python 3.0 .xrange() vai embora e .range() lhe dará comportamento agradável iterador de qualquer maneira.

xrange apenas armazena os parâmetros alcance e gera os números sobre a demanda. No entanto, a implementação C do Python restringe atualmente seus argumentos para longs C:

xrange(2**32-1, 2**32+1)  # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1)   # OK --> [4294967295L, 4294967296L]

Note que em Python 3.0 só há range e comporta-se como o xrange 2.x, mas sem as limitações de pontos finais mínimo e máximo.

xrange retorna um iterador e só mantém um número na memória de cada vez. gama mantém toda a lista de números na memória.

Do passar algum tempo com a Biblioteca de Referência . Quanto mais você está familiarizado com ele, quanto mais rápido você pode encontrar respostas a perguntas como esta. Especialmente importantes são os primeiros capítulos sobre incorporado objetos e tipos.

A vantagem do tipo xrange é que um objeto xrange será sempre tomar a mesma quantidade de memória, não importa o tamanho do intervalo que representa. Não existem vantagens de desempenho consistentes.

Outra forma de encontrar informações rápidas sobre uma construção Python é a docstring ea função de ajuda:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)

gama cria uma lista, por isso, se você fizer intervalo (1, 10000000) ele cria uma lista na memória com 10.000.000 elementos. xrange é um gerador, por isso avalia preguiçosamente.

Isso traz duas vantagens:

  1. Você pode iterar listas mais longas sem obter uma MemoryError.
  2. Como se resolve cada número preguiçosamente, se você parar de iteração inicial, você não vai perder tempo criando a lista inteira.

Estou chocado ninguém leia doc :

Esta função é muito semelhante ao range(), mas retorna um objeto xrange vez de uma lista. Este é um tipo de sequência opaco que produz os mesmos valores que a lista correspondente, sem, na verdade, armazenando-os todos ao mesmo tempo. A vantagem de xrange() sobre range() é mínima (desde xrange() ainda tem para criar os valores quando for solicitado), exceto quando uma gama muito grande é usado em uma máquina sedentos de memória ou quando todos os elementos do alcance nunca são usadas (como quando o laço é geralmente terminada com break).

É por razões de otimização.

range () irá criar uma lista de valores do início ao fim (0 .. 20 no seu exemplo). Isso vai se tornar uma operação cara em grandes intervalos.

xrange (), por outro lado é muito mais otimizado. ele só irá calcular o valor seguinte, quando necessário (através de um objeto de seqüência xrange) e não criar uma lista de todos os valores, como range () faz.

Você vai encontrar a vantagem de xrange sobre range neste exemplo simples:

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 4.49153590202 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 7.04547905922 seconds

O exemplo acima não reflete nada substancialmente melhor em caso de xrange.

Agora olhe para o caso seguinte, onde range é realmente muito lento, em comparação com xrange.

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 0.000764846801758 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer() 

print "time taken: ", (t2-t1)  # 2.78506207466 seconds

Com range, já cria uma lista 0-100,000,000 (demorado), mas xrange é um gerador e só gera números com base na necessidade, isto é, se a iteração continua.

Em Python-3, a implementação da funcionalidade range é mesma que a de xrange em Python-2, enquanto eles têm feito com a distância xrange em Python-3

Happy Codificação !!

range ():. intervalo (1, 10) retorna uma lista de 1 a 10 números e manter lista inteira na memória

xrange (): gama Like (), mas ao invés de retornar uma lista, retorna um objeto que gera os números no intervalo sob demanda. Para looping, este é ligeiramente mais rápido do que range () e mais memória eficiente. xrange () objeto como um iterador e gera os números sobre a demanda. (preguiçoso Avaliação)

In [1]: range(1,10)

Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: xrange(10)

Out[2]: xrange(10)

In [3]: print xrange.__doc__

xrange([start,] stop[, step]) -> xrange object

range(x,y) retorna uma lista de cada número entre x e y se você usar um loop for, então range é mais lento. Na verdade, range tem uma gama índice maior. range(x.y) irá imprimir uma lista de todos os números entre x e y

xrange(x,y) retornos xrange(x,y) mas se você usou um loop for, então xrange é mais rápido. xrange tem uma gama Índice menor. xrange não só irá imprimir xrange(x,y) mas ainda vai manter todos os números que estão nele.

[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)

Se você usar um loop for, então ele iria trabalhar

[In] for i in range(1,10):
        print i
[Out] 1
      2
      3
      4
      5
      6
      7
      8
      9
[In] for i in xrange(1,10):
         print i
[Out] 1
      2
      3
      4
      5
      6
      7
      8
      9

Não há muita diferença quando se usa loops, embora haja uma diferença quando apenas imprimi-lo!

Em Python 2.x

intervalo (x) retorna uma lista, que é criado na memória com elementos x.

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]

xrange (x) devolve um objecto xrange que é um obj gerador que gera os números em demanda. eles são computados durante for-loop (avaliação preguiçosa).

Para looping, este é ligeiramente mais rápido do que range () e mais eficiente de memória.

>>> b = xrange(5)
>>> b
xrange(5)

Ao testar gama contra xrange em um loop (eu sei que eu deveria usar timeit , mas isso foi rapidamente cortado-se da memória usando um exemplo simples compreensão da lista) eu encontrei o seguinte:

import time

for x in range(1, 10):

    t = time.time()
    [v*10 for v in range(1, 10000)]
    print "range:  %.4f" % ((time.time()-t)*100)

    t = time.time()
    [v*10 for v in xrange(1, 10000)]
    print "xrange: %.4f" % ((time.time()-t)*100)

que dá:

$python range_tests.py
range:  0.4273
xrange: 0.3733
range:  0.3881
xrange: 0.3507
range:  0.3712
xrange: 0.3565
range:  0.4031
xrange: 0.3558
range:  0.3714
xrange: 0.3520
range:  0.3834
xrange: 0.3546
range:  0.3717
xrange: 0.3511
range:  0.3745
xrange: 0.3523
range:  0.3858
xrange: 0.3997 <- garbage collection?

Ou, usando xrange no loop for:

range:  0.4172
xrange: 0.3701
range:  0.3840
xrange: 0.3547
range:  0.3830
xrange: 0.3862 <- garbage collection?
range:  0.4019
xrange: 0.3532
range:  0.3738
xrange: 0.3726
range:  0.3762
xrange: 0.3533
range:  0.3710
xrange: 0.3509
range:  0.3738
xrange: 0.3512
range:  0.3703
xrange: 0.3509

É o meu trecho de testar corretamente? Quaisquer comentários sobre a instância mais lento de xrange? Ou um exemplo melhor: -)

Algumas das outras respostas mencionar que Python 3 eliminado range de 2.x e xrange de 2.x renomeado para range. No entanto, a menos que você estiver usando 3.0 ou 3.1 (que ninguém deveria ser), é realmente um tipo um pouco diferente.

Como os 3,1 docs dizer:

objetos Range têm muito pouco comportamento: eles só apoiar a indexação, iteração, ea função len

.

No entanto, em 3.2+, range é uma sequência-lo cheio apoia fatias prolongados, e todos os métodos de collections.abc.Sequence com a mesma semântica como uma list. *

E, pelo menos em CPython e PyPy (os únicos dois 3.2+ implementações que existem atualmente), ele também tem implementações em tempo constante dos métodos index e count e o operador in (contanto que você só passá-lo inteiros) . Este 123456 in r significa escrever é razoável em 3.2+, enquanto em 2.7 ou 3.1 que seria uma idéia horrível.


* O fato de que issubclass(xrange, collections.Sequence) retornos True em 2,6-2,7 e 3,0-3,1 é um bug que foi fixado em 3,2 e não backported.

xrange () e range () em python funciona de forma semelhante como para o usuário, mas a diferença vem quando nós estamos falando sobre como a memória é alocada em usar tanto a função.

Quando estamos usando range () que alocar memória para todas as variáveis ??que está gerando, por isso não é recomendado para uso com maiores nenhum. de variáveis ??a serem gerados.

xrange (), por outro lado gerar apenas um valor específico de cada vez e só pode ser usado com o loop for para imprimir todos os valores necessários.

gama gera a lista inteira e devolve-lo. xrange não -. que gera os números na lista sob demanda

Leia o post seguinte para a comparação entre gama e xrange com análise gráfica.

Python gama Vs xrange

xrange utiliza uma iteração (gera valores em tempo real), gama retorna uma lista.

O quê?
range retorna uma lista estática em tempo de execução.
xrange retorna um object (que atua como um gerador, embora certamente não é um) a partir do qual os valores são gerados como e quando necessário.

Quando usar o que?

  • Use xrange se você deseja gerar uma lista para uma gama gigantesca, digamos 1 bilhão, especialmente quando você tem um "sistema sensível de memória" como um telefone celular.
  • Use range se você quiser iterar sobre a lista várias vezes.

PS:. Função range do Python 3.x == função xrange do Python 2.x

Em um requisito para a digitalização / impressão de itens 0-N, gama e obras xrange como segue.

range () - cria uma nova lista na memória e leva toda a 0 para itens N (totalmente n + 1) e os imprime. xrange (.) - cria uma instância iterador que varre os itens e mantém apenas o item encontrou actual na memória, portanto, utilizando mesma quantidade de memória o tempo todo

No caso do elemento necessário é um pouco no início da lista só então ele economiza uma boa quantidade de tempo e memória.

A diferença diminui para argumentos menores para range(..) / xrange(..):

$ python -m timeit "for i in xrange(10111):" " for k in range(100):" "  pass"
10 loops, best of 3: 59.4 msec per loop

$ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" "  pass"
10 loops, best of 3: 46.9 msec per loop

Neste caso xrange(100) é apenas cerca de 20% mais eficiente.

Todo mundo já explicou muito. Mas eu queria ver por mim mesmo. Eu uso python3. Então, eu abri o monitor de recursos (no Windows!), E em primeiro lugar, executado o seguinte comando em primeiro lugar:

a=0
for i in range(1,100000):
    a=a+i

e então verificado a mudança na memória em uso ". Foi insignificante. Então, eu corri o seguinte código:

for i in list(range(1,100000)):
    a=a+i

E levou uma grande parte da memória para uso, instantaneamente. E, eu estava convencido. Você pode experimentar por si próprio.

Se você estiver usando Python 2X, em seguida, substituir 'range ()' com 'xrange ()' no primeiro código e 'lista (range ())' com 'range ()'.

Gama retorna um lista , enquanto xrange retorna um xrange objeto que leva a mesma memória, independentemente da faixa tamanho, como neste caso, apenas um elemento é gerado e disponível por iteração que, em caso de utilização de gama, todos os elementos são gerados ao mesmo tempo e estão disponíveis na memória.

intervalo:. -Range irá preencher tudo de meios once.which cada número da gama vai ocupar a memória

xrange: -xrange é algo como gerador, ele vai entrar em foto quando quiser que o intervalo de números, mas você não quer que eles sejam armazenados, como quando você deseja usar no para loop.so eficiente de memória

De docs de ajuda.

Python 2.7.12

>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

>>> print xrange.__doc__
xrange(stop) -> xrange object
xrange(start, stop[, step]) -> xrange object

Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand.  For looping, this is 
slightly faster than range() and more memory efficient.

Python 3.5.2

>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object

Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).

>>> print(xrange.__doc__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined

A diferença é aparente. Em Python 2.x, range retorna uma lista, xrange retorna um objeto xrange que é iterable.

Em Python 3.x, torna-se range xrange do Python 2.x, e xrange é removido.

Além disso, se fazer list(xrange(...)) será equivalente a range(...).

Assim list é lento.

Além disso xrange realmente não terminar totalmente a seqüência

Então é por isso que não é uma lista, é um objeto xrange

Veja este pós para encontrar diferença entre gama e xrange :

Para citar:

range retorna exatamente o que você pensa: uma lista de consecutivo números inteiros, de um comprimento definido a partir de 0. xrange, no entanto, retorna um "objeto xrange" , que atua muito como um iterador

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top