Imprimir uma lista na ordem inversa com range ()?

364

Como você pode produzir a seguinte lista range()no Python?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
ramesh.mimit
fonte
E quanto a [* intervalo (9, -1, -1)]? Super pitonico!
onofricamila

Respostas:

561

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 rangepara 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.

Michał Šrajer
fonte
13
Embora seja "menos eficiente". E você não pode fazer operações de corte nele.
Jakob Bowyer 02/02
6
Essa resposta é muito clara e fácil de entender, mas precisa ser range(10), não range(9). Além disso, se você quiser uma lista completa (para fatiar, etc.), faça list(reversed(range(10))).
John Y
5
Isso produz um iterador, o OP solicitou um resultado na forma de uma lista.
btk
6
O uso de "reverso" com o gerador python (assumindo que falamos do intervalo do Python 3 embutido) é apenas conceitualmente errado e ensina hábitos errados de não considerar a complexidade da memória / processamento ao programar em linguagem de alto nível.
Thedk 23/03
7
No Python3, reversednão aceita geradores em geral, mas aceita range. Por que reversed(range(10000))precisaria alocar memória para toda a lista? rangepode retornar um objeto que implementa o __reversed__método que permite iteração reversa eficiente?
Avmohan #
312

Use a função interna 'range'. A assinatura é range(start, stop, step). Isso produz uma sequência que gera números, começando com starte terminando se stoptiver 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 rangeobjeto que não é da lista , que funciona efetivamente como uma lista somente leitura (mas usa muito menos memória, principalmente para grandes intervalos).

Mr. B
fonte
11
Pode me explicar isso tão bem, também pode fazer o favor de me recomendar qualquer / livro pdf site para python
ramesh.mimit
8
@ramesh Se você rodar 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)
Michael Mrozek 02/09
3
@ ramesh.mimit: Basta ir ao site oficial do Python. Há documentação completa lá, incluindo um ótimo tutorial.
John Y
5
Realmente, esta é a resposta correta, mas poderia ser explicada com mais clareza. range(start, stop, step) - comece no número starte produza resultados, a menos que stoptenha sido alcançado, movendo-se a stepcada vez.
Sr. B
43

Você pode usar o range(10)[::-1]que é a mesma coisa range(9, -1, -1)e sem dúvida mais legível (se você estiver familiarizado com o sequence[::-1]idioma comum do Python).

Martineau
fonte
28

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 .

Lobo
fonte
3
Eu fiz meus próprios horários antes de ler esta resposta e obtive os mesmos resultados.
Todd Owen
13
for i in range(8, 0, -1)

vai resolver esse problema. Ele produzirá 8 para 1 e -1 significa uma lista invertida

Jutta
fonte
10

Não faz sentido usar, reverseporque 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 stepe define -1, outros parâmetros devem ser ajustados de acordo:

  1. Fornecer parada parâmetro como -1(é valor anterior stop - 1, stopfoi igual a 0).
  2. Como parâmetro inicial, use 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]
Andriy Ivaneyko
fonte
6
Sinceramente, acho isso menos intuitivo do quereversed(range(n))
Nicholas Hamilton
11
@NicholasHamilton Concordo com você, no entanto ideia por trás dessa resposta é usar menos recursos ... (e a pergunta era sobre o uso de apenas função gama :))
Andriy Ivaneyko
Ok, não se preocupe, acho que depende da situação. Por exemplo, se a função gama é utilizado como o índice para um ciclo, em seguida, ele terá um efeito limitado, no entanto, se for utilizado dentro de um circuito externo, então o custo será composto ...
Nicholas Hamilton
8

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 :)

Jaime RGP
fonte
bom ter alguns números :) - por que você não adicionou range(1000000000-1,-1,-1)também?
Lobo
... melhor não tentar timeit range(1000000000-1,-1,-1)na linha de comando, em vez ver os meus resultados :-)
Lobo
6

O requisito nesta pergunta exige um número listinteiro 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]
un33k
fonte
2
Eu realmente gosto do triplo-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.
Lobo
5

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

Mr. Suryaa Jha
fonte
5

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:

  1. Os len()índices de suporte e de número inteiro via[]
  2. Ou tem __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.

Shital Shah
fonte
3

eu acredito que isso pode ajudar,

range(5)[::-1]

abaixo é o uso:

for i in range(5)[::-1]:
    print i 
dineshsprabu
fonte
3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Asinox
fonte
13
Sua resposta mostra por que reversed(range(10))é menos propensa a erros. Sem ofensa Asinox. Apenas uma observação honesta.
Michał Šrajer
Não sei se é padrão deixar respostas erradas em exibição. Posso ou alguém corrigi-lo ou até removê-lo?
Sinekonata
3
@ sine, não é só deixar e perguntar como ele acumulou 3 votos positivos ... Suponho que você possa sinalizá-lo para atenção do moderador (duplicado da resposta de 18 meses antes, exceto quebrado), sem ter certeza se o excluiriam ou não.
OGHaza
Para todas as referências futuras: apenas o código não é VLQ e as respostas erradas também não devem ser sinalizadas . Voto negativo e seguir em frente, mas a sinalização está errada nesse caso, seja NAA ou sinalização mod. - Do comentário
Zoe
2

Usando sem [:: - 1] ou invertido -

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")
rhel.user
fonte
6
Por que alguém deveria escrever isso em vez de "python!"[::-1]?
Daniel
1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jason
fonte
1

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.

user7420740
fonte
Essa parece ser a solução sugerida em uma resposta anterior . Parece também que você pode estar tentando comentar uma resposta anterior diferente - precisará obter um pouco mais de reputação antes de fazer isso.
Grisha Levit
1

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.

Vishal Kumar
fonte
0
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.

user3807372
fonte
0

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))

Resposta de Jason :

%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)

resposta de martineau :

%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Resposta de Michał Šrajer :

%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

resposta de bene :

%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.timeitsob o capô. Testado para Python 3.7.3

pkuderov
fonte