Como você pode produzir a seguinte lista range()
no Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Como você pode produzir a seguinte lista range()
no Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Respostas:
use a reversed()
função:
reversed(range(10))
É muito mais significativo.
Atualizar:
Se você deseja que seja uma lista (como btk apontou):
list(reversed(range(10)))
Atualizar:
Se você deseja usar apenas range
para obter o mesmo resultado, pode usar todos os seus parâmetros.range(start, stop, step)
Por exemplo, para gerar uma lista [5,4,3,2,1,0]
, você pode usar o seguinte:
range(5, -1, -1)
Pode ser menos intuitivo, mas como os comentários mencionam, isso é mais eficiente e o uso correto do intervalo para lista invertida.
range(10)
, não range(9)
. Além disso, se você quiser uma lista completa (para fatiar, etc.), faça list(reversed(range(10)))
.
reversed
não aceita geradores em geral, mas aceita range
. Por que reversed(range(10000))
precisaria alocar memória para toda a lista? range
pode retornar um objeto que implementa o __reversed__
método que permite iteração reversa eficiente?
Use a função interna 'range'. A assinatura é range(start, stop, step)
. Isso produz uma sequência que gera números, começando com start
e terminando se stop
tiver sido alcançado, excluindo stop
.
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
No Python 3, isso produz um range
objeto que não é da lista , que funciona efetivamente como uma lista somente leitura (mas usa muito menos memória, principalmente para grandes intervalos).
help(range)
em um shell python, ele mostrará os argumentos. Eles são o número para começar, o número para terminar (exclusivo) e a etapa a ser executada; portanto, começa às 9 e subtrai 1 até chegar a -1 (nesse ponto pára sem retornar, e é por isso que o intervalo termina em 0)
range(start, stop, step)
- comece no número start
e produza resultados, a menos que stop
tenha sido alcançado, movendo-se a step
cada vez.
Para quem está interessado na "eficiência" das opções coletadas até o momento ...
A resposta de Jaime RGP me levou a reiniciar o computador depois de cronometrar a solução um tanto "desafiadora" de Jason, literalmente, seguindo minha própria sugestão (via comentário). Para poupar os curiosos de você do tempo de inatividade, apresento aqui meus resultados (o pior primeiro):
A resposta de Jason (talvez apenas uma excursão ao poder da compreensão da lista ):
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
resposta de martineau (legível se você estiver familiarizado com a sintaxe de fatias estendida ):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
Resposta de Michał Šrajer (a aceita, muito legível):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
resposta de bene (a primeira, mas muito superficial na época ):
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
É fácil lembrar a última opção usando a range(n-1,-1,-1)
notação de Val Neekman .
reverse
porque o método range pode retornar uma lista invertida.Quando você tem iteração sobre n itens e deseja substituir a ordem da lista retornada, range(start, stop, step)
você deve usar o terceiro parâmetro do intervalo que o identifica step
e define -1
, outros parâmetros devem ser ajustados de acordo:
-1
(é valor anterior stop - 1
, stop
foi igual a 0
).n-1
.Portanto, o equivalente ao intervalo (n) na ordem inversa seria:
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
Legibilidade à parte, reversed(range(n))
parece ser mais rápido que range(n)[::-1]
.
$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop
Apenas se alguém estava se perguntando :)
range(1000000000-1,-1,-1)
também?
timeit range(1000000000-1,-1,-1)
na linha de comando, em vez ver os meus resultados :-)
O requisito nesta pergunta exige um número list
inteiro de tamanho 10 em ordem decrescente. Então, vamos produzir uma lista em python.
# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------
# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>
# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
-1
É exatamente esse padrão que facilita a manutenção wrap one's head around this
- Hoje eu aprendi que, se realmente precisa ser eficiente , use range(n-1, -1, -1)
ao percorrer um intervalo em ordem inversa.
Você pode imprimir números reversos com o intervalo () como BIF,
for number in range ( 10 , 0 , -1 ) :
print ( number )
A produção será [10,9,8,7,6,5,4,3,2,1]
range () - range (início, fim, incremento / decremento) onde o início é inclusivo, o fim é exclusivo e o incremento pode ser qualquer número e se comportar como etapa
A pergunta mais frequente é se é range(9, -1, -1)
melhor do que reversed(range(10))
no Python 3? Pessoas que trabalharam em outros idiomas com iteradores imediatamente tendem a pensar que reversed () deve armazenar em cache todos os valores e retornar na ordem inversa. O problema é que o reversed()
operador do Python não funciona se o objeto for apenas um iterador. O objeto deve ter um dos dois abaixo para reverso () funcionar:
len()
índices de suporte e de número inteiro via[]
__reversed__()
método implementado.Se você tentar usar reversed () no objeto que não possui nenhum dos itens acima, você obterá:
>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible
Portanto, em resumo, o Python reversed()
é destinado apenas a objetos do tipo matriz e, portanto, deve ter o mesmo desempenho que a iteração direta.
Mas que tal range()
? Isso não é um gerador? No Python 3, ele é gerador, mas está envolvido em uma classe que implementa os dois acima. Portanto range(100000)
, não ocupa muita memória, mas ainda suporta indexação e reversão eficientes.
Portanto, em resumo, você pode usar reversed(range(10))
sem afetar o desempenho.
eu acredito que isso pode ajudar,
range(5)[::-1]
abaixo é o uso:
for i in range(5)[::-1]:
print i
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))
é menos propensa a erros. Sem ofensa Asinox. Apenas uma observação honesta.
Você não precisa necessariamente usar a função range, basta fazer a lista [:: - 1], que deve retornar a lista em ordem inversa rapidamente, sem usar nenhuma adição.
Suponha que você tenha uma lista, chame-a de = {1,2,3,4,5} Agora, se você quiser imprimir a lista ao contrário, basta usar o código a seguir.
a.reverse
for i in a:
print(i)
Eu sei que você perguntou usando o intervalo, mas já está respondido.
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
É a forma correta. Se você usar
reversed(range(10))
você não receberá um caso 0. Por exemplo, digamos que seu número 10 não seja um número mágico e uma variável que você está usando para iniciar a pesquisa de maneira inversa. Se o seu n caso for 0, o inverso (intervalo (0)) não será executado, o que está errado se você por acaso tiver um único objeto no índice zero.
Eu pensei que muitos (como eu) poderiam estar mais interessados em um caso comum de percorrer uma lista existente em ordem inversa , como está declarado no título, em vez de apenas gerar índices para essa travessia.
Mesmo assim, todas as respostas certas ainda estão perfeitamente adequadas para este caso, quero ressaltar que a comparação de desempenho feita na resposta de Wolf é apenas para gerar índices. Então, eu fiz benchmark semelhante para percorrer uma lista existente em ordem inversa.
TL; DR a[::-1]
é o mais rápido.
Pré-requisitos:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Como você vê, nesse caso, não há necessidade de gerar índices explicitamente; portanto, o método mais rápido é o que realiza menos ações extras.
NB: Eu testei no JupyterLab, que tem um prático "comando mágico" %timeit
. Ele usa padrão timeit.timeit
sob o capô. Testado para Python 3.7.3