Respostas:
Você pode fazer uso da reversed
função para isso como:
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
Observe que reversed(...)
não retorna uma lista. Você pode obter uma lista invertida usando list(reversed(array))
.
reverse
pode ser mais rápido, se você não precisar transmitir para a lista posteriormente.
reversed()
vez de cortar? Leia o Zen do Python, regra número 7: A legibilidade conta!
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
A sintaxe de fatia estendida é explicada bem no Python What's new Entry for release2.3.5
Por solicitação especial em um comentário, esta é a documentação da fatia mais atual .
reversed
retorna um listreverseiterator
objeto (Python 2.7.x), que deve ser iterado através de + fatiamento reverso retorna uma lista / tupla / str invertida (dependendo do que você está fatiando). @ Einar Petersen que está invertendo uma string, para que a saída esteja correta. Tente:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]
Ou
>>> L[::-1]
[40, 20, 10, 0]
L=L[::-1]
para realmente reverter a lista de outra forma você está retornando somente os valores em sentido inverso
b = l[-n:] b.reverse() l = b + l[:len(l) - n]
Eu acho que a melhor maneira de reverter uma lista em Python é fazer:
a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]
O trabalho está concluído e agora você tem uma lista invertida.
Para reverter a mesma lista, use:
array.reverse()
Para atribuir lista invertida a alguma outra lista, use:
newArray = array[::-1]
Usar fatias, por exemplo, array = array [:: - 1], é um truque interessante e muito pitonico, mas talvez um pouco obscuro para iniciantes. Usar o método reverse () é uma boa maneira de codificar dia a dia, porque é facilmente legível.
No entanto, se você precisar reverter uma lista como em uma pergunta de entrevista, provavelmente não poderá usar métodos incorporados como esses. O entrevistador examinará como você aborda o problema, e não a profundidade do conhecimento em Python; é necessária uma abordagem algorítmica. O exemplo a seguir, usando uma troca clássica, pode ser uma maneira de fazer isso:
def reverse_in_place(lst): # Declare a function
size = len(lst) # Get the length of the sequence
hiindex = size - 1
its = size/2 # Number of iterations required
for i in xrange(0, its): # i is the low index pointer
temp = lst[hiindex] # Perform a classic swap
lst[hiindex] = lst[i]
lst[i] = temp
hiindex -= 1 # Decrement the high index pointer
print "Done!"
# Now test it!!
array = [2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]
print array # Print the original sequence
reverse_in_place(array) # Call the function passing the list
print array # Print reversed list
**The result:**
[2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]
Done!
[654, 124, 24, 7, 1, 65, 60, 32, 27, 25, 19, 12, 9, 8, 5, 2]
Observe que isso não funcionará em tuplas ou seqüências de cadeias, porque cadeias e tuplas são imutáveis, ou seja, você não pode gravá-las para alterar elementos.
lst[hiindex], lst[i] = lst[i], lst[hiindex]
, eu acho ... ;-)
array[::-1]
é perfeitamente legível e perfeitamente explícito se você conhece Python . "Legível" não significa "alguém que nunca usou o Python slicing antes deve poder lê-lo"; a [::-1]
fatia de reversão é um idioma ridiculamente comum no Python (você o encontrará no código existente o tempo todo) e é perfeitamente legível se você usa regularmente o Python . Claro, first10 = []
, for i in range(10): first10.append(array[i])
é clara e explícita, mas isso não significa que seja melhor do que first10 = array[:10]
.
Acho (ao contrário de algumas outras sugestões) que l.reverse()
é de longe a maneira mais rápida de reverter uma longa lista no Python 3 e 2. Gostaria de saber se outras pessoas podem replicar esses tempos.
l[::-1]
provavelmente é mais lento porque copia a lista antes de revertê-la. A adição da list()
chamada no iterador feita por reversed(l)
deve adicionar uma sobrecarga. Obviamente, se você deseja uma cópia da lista ou de um iterador, use os respectivos métodos, mas se desejar reverter a lista, l.reverse()
parece ser o caminho mais rápido.
Funções
def rev_list1(l):
return l[::-1]
def rev_list2(l):
return list(reversed(l))
def rev_list3(l):
l.reverse()
return l
Lista
l = list(range(1000000))
Temporizações do Python 3.5
timeit(lambda: rev_list1(l), number=1000)
# 6.48
timeit(lambda: rev_list2(l), number=1000)
# 7.13
timeit(lambda: rev_list3(l), number=1000)
# 0.44
Horários do Python 2.7
timeit(lambda: rev_list1(l), number=1000)
# 6.76
timeit(lambda: rev_list2(l), number=1000)
# 9.18
timeit(lambda: rev_list3(l), number=1000)
# 0.46
list.reverse
é o mais rápido, porque ele inverte no lugar
list.reverse()
é o mais rápido, mas está penalizando reversed
(o que é melhor usado quando você não deseja um novo list
, apenas para iterar um existente list
na ordem inversa sem alterar o original) e a fatia (que também evita a alteração do original) list
e geralmente é mais rápido do que reversed
quando a entrada é pequena). Sim, se você não precisar da cópia, qualquer coisa que a copie será mais cara, mas na maioria das vezes, não deseja alterar o valor original.
reversed
ainda perde paralist.reverse()
isso, mas, como não altera a entrada list
, é melhor em muitos casos. A perda para reversed
é pequena (~ 1/6 a mais que list.reverse()
).
for x in array[::-1]:
do stuff
>>> list1 = [1,2,3]
>>> reversed_list = list(reversed(list1))
>>> reversed_list
>>> [3, 2, 1]
array=[0,10,20,40]
for e in reversed(array):
print e
Usar reverso (matriz) seria a melhor rota provável.
>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>> print item
Se você precisar entender como implementar isso sem usar o built-in reversed
.
def reverse(a):
midpoint = len(a)/2
for item in a[:midpoint]:
otherside = (len(a) - a.index(item)) - 1
temp = a[otherside]
a[otherside] = a[a.index(item)]
a[a.index(item)] = temp
return a
Isso deve levar tempo O (N).
Existem várias boas respostas, mas se espalham e a maioria não indica as diferenças fundamentais de cada abordagem.
No geral, é melhor usar funções / métodos internos para reverter, como acontece com praticamente qualquer função. Nesse caso, eles são aproximadamente 2 a 8 vezes mais rápidos em listas curtas (10 itens) e até ~ 300 vezes mais rápidos em listas longas, em comparação com os meios criados manualmente de indexação. Isso faz sentido, pois eles têm especialistas para criá-los, examinar e otimizar. Eles também são menos propensos a defeitos e mais propensos a lidar com casos de borda e canto.
Considere também se você deseja:
object.reverse()
métodoreversed(object)
criar o iteradorobject[::-1]
Aqui está o início do meu script de teste para os métodos abordados. Coloque todos os trechos de código nesta resposta juntos para criar um script que execute todas as maneiras diferentes de reverter uma lista e tempo cada uma (saída mostrada na última seção).
from timeit import timeit
from copy import copy
def time_str_ms(t):
return '{0:8.2f} ms'.format(t * 1000)
Se o objetivo é apenas reverter a ordem dos itens em uma lista existente, sem passar por cima deles ou obter uma cópia para trabalhar, use a <list>.reverse()
função Execute isso diretamente em um objeto de lista e a ordem de todos os itens será revertida:
Observe que o seguinte reverterá a variável original que é fornecida, embora ela também retorne a lista invertida. ou seja, você pode criar uma cópia usando esta função de saída. Normalmente, você não faria uma função para isso, mas eu fiz isso para usar o código de temporização no final.
Testaremos o desempenho dessas duas maneiras - primeiro apenas revertendo uma lista no local (altera a lista original), depois copiando a lista e revertendo-a depois.
def rev_in_place(mylist):
mylist.reverse()
return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()
return a
obj[::-1]
O método de fatiamento de índice interno permite que você faça uma cópia de parte de qualquer objeto indexado.
A sintaxe genérica é: <object>[first_index:last_index:step]
. Para explorar corte para criar uma simples lista invertida, use: <list>[::-1]
. Ao deixar uma opção vazia, ela os define como padrão do primeiro e do último elemento do objeto (revertido se o tamanho da etapa for negativo).
A indexação permite usar números negativos, que são contados do final do índice do objeto para trás (ie -2 é o penúltimo item). Quando o tamanho da etapa for negativo, ele começará com o último item e indexará para trás por esse valor. Há alguma lógica de início-fim associada a isso que foi otimizada.
def rev_slice(mylist):
a = mylist[::-1]
return a
reversed(obj)
função de iteradorExiste uma reversed(indexed_object)
função:
Teste com um iterador bruto e criando uma lista a partir do iterador.
def reversed_iterator(mylist):
a = reversed(mylist)
return a
def reversed_with_list(mylist):
a = list(reversed(mylist))
return a
Como o tempo mostrará, criar seus próprios métodos de indexação é uma má idéia. Use os métodos internos, a menos que você precise fazer algo realmente personalizado.
Dito isto, não há uma penalidade enorme com tamanhos de lista menores, mas quando você aumenta a penalidade se torna tremenda. Tenho certeza de que meu código abaixo pode ser otimizado, mas continuarei com os métodos internos.
def rev_manual_pos_gen(mylist):
max_index = len(mylist) - 1
return [ mylist[max_index - index] for index in range(len(mylist)) ]
def rev_manual_neg_gen(mylist):
## index is 0 to 9, but we need -1 to -10
return [ mylist[-index-1] for index in range(len(mylist)) ]
def rev_manual_index_loop(mylist):
a = []
reverse_index = len(mylist) - 1
for index in range(len(mylist)):
a.append(mylist[reverse_index - index])
return a
def rev_manual_loop(mylist):
a = []
reverse_index = len(mylist)
for index, _ in enumerate(mylist):
reverse_index -= 1
a.append(mylist[reverse_index])
return a
A seguir, o restante do script, para cronometrar cada método de reversão. Ele mostra que a inversão no local obj.reverse()
e a criação do reversed(obj)
iterador são sempre as mais rápidas, enquanto o uso de fatias é a maneira mais rápida de criar uma cópia.
Também prova não tentar criar uma maneira de fazê-lo por conta própria, a menos que você precise!
loops_to_test = 100000
number_of_items = 10
list_to_reverse = list(range(number_of_items))
if number_of_items < 15:
print("a: {}".format(list_to_reverse))
print('Loops: {:,}'.format(loops_to_test))
# List of the functions we want to test with the timer, in print order
fcns = [rev_in_place, reversed_iterator, rev_slice, rev_copy_reverse,
reversed_with_list, rev_manual_pos_gen, rev_manual_neg_gen,
rev_manual_index_loop, rev_manual_loop]
max_name_string = max([ len(fcn.__name__) for fcn in fcns ])
for fcn in fcns:
a = copy(list_to_reverse) # copy to start fresh each loop
out_str = ' | out = {}'.format(fcn(a)) if number_of_items < 15 else ''
# Time in ms for the given # of loops on this fcn
time_str = time_str_ms(timeit(lambda: fcn(a), number=loops_to_test))
# Get the output string for this function
fcn_str = '{}(a):'.format(fcn.__name__)
# Add the correct string length to accommodate the maximum fcn name
format_str = '{{fx:{}s}} {{time}}{{rev}}'.format(max_name_string + 4)
print(format_str.format(fx=fcn_str, time=time_str, rev=out_str))
Os resultados mostram que o dimensionamento funciona melhor com os métodos internos mais adequados para uma determinada tarefa. Em outras palavras, à medida que a contagem de elementos do objeto aumenta, os métodos internos começam a ter resultados de desempenho muito superiores.
Também é melhor usar o melhor método interno que alcança diretamente o que você precisa do que encadear as coisas. ou seja, fatiar é melhor se você precisar de uma cópia da lista invertida - é mais rápido do que criar uma lista a partir da reversed()
função e mais rápido do que fazer uma cópia da lista e, em seguida, fazer um no local obj.reverse()
. Mas se qualquer um desses métodos é realmente tudo o que você precisa, eles são mais rápidos, mas nunca mais que o dobro da velocidade. Enquanto isso - métodos manuais personalizados podem demorar mais tempo, especialmente em listas muito grandes.
Para dimensionar, com uma lista de 1000 itens, a reversed(<list>)
chamada de função leva ~ 30 ms para configurar o iterador, a reversão no local leva apenas ~ 55 ms, usando o método de fatia leva ~ 210 ms para criar uma cópia da lista completa invertida, mas o método manual mais rápido que fiz levou ~ 8400 ms !!
Com 2 itens na lista:
a: [0, 1]
Loops: 100,000
rev_in_place(a): 24.70 ms | out = [1, 0]
reversed_iterator(a): 30.48 ms | out = <list_reverseiterator object at 0x0000020242580408>
rev_slice(a): 31.65 ms | out = [1, 0]
rev_copy_reverse(a): 63.42 ms | out = [1, 0]
reversed_with_list(a): 48.65 ms | out = [1, 0]
rev_manual_pos_gen(a): 98.94 ms | out = [1, 0]
rev_manual_neg_gen(a): 88.11 ms | out = [1, 0]
rev_manual_index_loop(a): 87.23 ms | out = [1, 0]
rev_manual_loop(a): 79.24 ms | out = [1, 0]
Com 10 itens na lista:
rev_in_place(a): 23.39 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_iterator(a): 30.23 ms | out = <list_reverseiterator object at 0x00000290A3CB0388>
rev_slice(a): 36.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_copy_reverse(a): 64.67 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_with_list(a): 50.77 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_pos_gen(a): 162.83 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_neg_gen(a): 167.43 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_index_loop(a): 152.04 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_loop(a): 183.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
E com 1000 itens na lista:
rev_in_place(a): 56.37 ms
reversed_iterator(a): 30.47 ms
rev_slice(a): 211.42 ms
rev_copy_reverse(a): 295.74 ms
reversed_with_list(a): 418.45 ms
rev_manual_pos_gen(a): 8410.01 ms
rev_manual_neg_gen(a): 11054.84 ms
rev_manual_index_loop(a): 10543.11 ms
rev_manual_loop(a): 15472.66 ms
Se você deseja armazenar os elementos da lista invertida em alguma outra variável, pode usar revArray = array[::-1]
ou revArray = list(reversed(array))
.
Mas a primeira variante é um pouco mais rápida:
z = range(1000000)
startTimeTic = time.time()
y = z[::-1]
print("Time: %s s" % (time.time() - startTimeTic))
f = range(1000000)
startTimeTic = time.time()
g = list(reversed(f))
print("Time: %s s" % (time.time() - startTimeTic))
Resultado:
Time: 0.00489711761475 s
Time: 0.00609302520752 s
timeit
.
No Python, a ordem das listas também pode ser manipulada com a classificação , organizando suas variáveis em ordem numérica / alfabética:
print(sorted(my_list))
my_list.sort(), print(my_list)
Você pode classificar com a bandeira "reverse = True" :
print(sorted(my_list, reverse=True))
ou
my_list.sort(reverse=True), print(my_list)
Talvez você não queira classificar valores, mas apenas reverter os valores. Então podemos fazer assim:
print(list(reversed(my_list)))
** Os números têm prioridade sobre o alfabeto na ordem de listagem. A organização dos valores do Python é incrível.
Usando alguma lógica da velha escola para praticar para entrevistas.
Trocar números da frente para trás. Usando dois ponteiros
index[0] and index[last]
def reverse(array):
n = array
first = 0
last = len(array) - 1
while first < last:
holder = n[first]
n[first] = n[last]
n[last] = holder
first += 1
last -= 1
return n
input -> [-1 ,1, 2, 3, 4, 5, 6]
output -> [6, 1, 2, 3, 4, 5, -1]
Você também pode usar o complemento bit a bit do índice da matriz para percorrer a matriz ao contrário:
>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]
Faça o que fizer, não faça dessa maneira.
Outra solução seria usar numpy.flip para esse
import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]
A rigor, a questão não é como retornar uma lista ao contrário, mas como reverter uma lista com um exemplo de nome de lista array
.
Para inverter uma lista chamada "array"
use array.reverse()
.
O método de fatia incrivelmente útil, conforme descrito, também pode ser usado para reverter uma lista no local, definindo a lista como uma modificação fatiada de si mesma usando array = array[::-1]
.
array[:] = array[::-1]
def reverse(text):
output = []
for i in range(len(text)-1, -1, -1):
output.append(text[i])
return output
Com uma quantidade mínima de funções integradas, assumindo que as configurações da entrevista
array = [1, 2, 3, 4, 5, 6,7, 8]
inverse = [] #create container for inverse array
length = len(array) #to iterate later, returns 8
counter = length - 1 #because the 8th element is on position 7 (as python starts from 0)
for i in range(length):
inverse.append(array[counter])
counter -= 1
print(inverse)
A tradução mais direta de seus requisitos para Python é esta for
declaração:
for i in xrange(len(array) - 1, -1, -1):
print i, array[i]
Isso é um tanto enigmático, mas pode ser útil.
def reverse(my_list):
L = len(my_list)
for i in range(L/2):
my_list[i], my_list[L-i - 1] = my_list[L-i-1], my_list[i]
return my_list
//
operador de divisão de piso.
Você sempre pode tratar a lista como uma pilha, apenas retirando os elementos da parte superior da pilha no final da lista. Dessa forma, você tira proveito das características first in last out de uma pilha. Claro que você está consumindo a primeira matriz. Eu gosto desse método, pois é bastante intuitivo, pois você vê uma lista sendo consumida no back-end enquanto a outra é criada no front-end.
>>> l = [1,2,3,4,5,6]; nl=[]
>>> while l:
nl.append(l.pop())
>>> print nl
[6, 5, 4, 3, 2, 1]
list_data = [1,2,3,4,5]
l = len(list_data)
i=l+1
rev_data = []
while l>0:
j=i-l
l-=1
rev_data.append(list_data[-j])
print "After Rev:- %s" %rev_data
usar
print(reversed(list_name))
Aqui está uma maneira de avaliar preguiçosamente o inverso usando um gerador :
def reverse(seq):
for x in range(len(seq), -1, -1): #Iterate through a sequence starting from -1 and increasing by -1.
yield seq[x] #Yield a value to the generator
Agora repita assim:
for x in reverse([1, 2, 3]):
print(x)
Se você precisar de uma lista:
l = list(reverse([1, 2, 3]))
Existem 3 métodos para obter a lista invertida:
Método de corte 1: reversed_array = array[-1::-1]
Método de corte 2:
reversed_array2 = array[::-1]
Usando a função interna: reversed_array = array.reverse()
A terceira função, na verdade, reverteu o objeto da lista no local. Isso significa que nenhuma cópia dos dados originais é mantida. Essa é uma boa abordagem se você não quiser manter a versão antiga. Mas não parece ser uma solução se você deseja a versão original e invertida.
>>> l = [1, 2, 3, 4, 5]
>>> print(reduce(lambda acc, x: [x] + acc, l, []))
[5, 4, 3, 2, 1]
l[::-1]
e ao mesmo tempo muito menos legível. A programação funcional em Python é infelizmente bastante lenta.