Ответы:
Вы можете использовать reversed
функцию для этого как:
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
Обратите внимание, что reversed(...)
не возвращает список. Вы можете получить обратный список, используя list(reversed(array))
.
reverse
может быть быстрее, хотя, если вам не нужно приводить к списку впоследствии.
reversed()
вместо нарезки? Прочтите Zen of Python, правило № 7: Читаемость важна!
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
Расширенный синтаксис слайса хорошо объясняется в Python. Что нового?2.3.5
По специальному запросу в комментарии это самая последняя документация по срезам .
reversed
возвращает listreverseiterator
объект (Python 2.7.x), который затем должен быть повторен - обратная нарезка возвращает обратный список / кортеж / str (в зависимости от того, что вы нарезаете). @Einar Petersen, который переворачивает строку, поэтому вывод правильный. Попробуйте: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]
Или
>>> L[::-1]
[40, 20, 10, 0]
L=L[::-1]
чтобы фактически перевернуть список, иначе вы только возвращаете значения в обратном порядке
b = l[-n:] b.reverse() l = b + l[:len(l) - n]
Я думаю, что лучший способ перевернуть список в Python - это сделать:
a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]
Работа выполнена, и теперь у вас есть обратный список.
Для обращения того же списка используйте:
array.reverse()
Чтобы перевернуть список в другой список, используйте:
newArray = array[::-1]
Использование нарезки, например, array = array [:: - 1], является изящным трюком и очень питонским, но, возможно, немного неясным для новичков. Использование метода reverse () - это хороший способ повседневного кодирования, потому что он легко читается.
Однако, если вам нужно изменить список на месте, как в вопросе об интервью, вы, скорее всего, не сможете использовать встроенные методы, подобные этим. Интервьюер будет смотреть на то, как вы подходите к проблеме, а не на глубину знаний Python, требуется алгоритмический подход. Следующий пример, использующий классический своп, может быть одним из способов сделать это:
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]
Обратите внимание, что это не будет работать с кортежами или последовательностями строк, потому что строки и кортежи являются неизменными, т. Е. Вы не можете записывать в них изменения элементов.
lst[hiindex], lst[i] = lst[i], lst[hiindex]
, я думаю ... ;-)
array[::-1]
отлично читается и явно, если вы знаете Python . «Читаемый» не означает, что «тот, кто никогда раньше не использовал нарезку Python, должен уметь читать его»; [::-1]
реверсивный ломтик смехотворно общие идиомы в Python (вы будете сталкиваться его в существующем коде все время), и это прекрасно читается , если вы регулярно использовать Python . Конечно, first10 = []
, for i in range(10): first10.append(array[i])
ясно и четко, но это не делает его лучше first10 = array[:10]
.
Я считаю (вопреки некоторым другим предложениям), что l.reverse()
на сегодняшний день это самый быстрый способ перевернуть длинный список в Python 3 и 2. Мне было бы интересно узнать, могут ли другие копировать эти моменты времени.
l[::-1]
вероятно, медленнее, потому что он копирует список до его обращения. Добавление list()
вызова вокруг итератора reversed(l)
должно добавить некоторые накладные расходы. Конечно, если вам нужна копия списка или итератор, используйте эти соответствующие методы, но если вы хотите просто перевернуть список, то, l.reverse()
похоже, самый быстрый способ.
функции
def rev_list1(l):
return l[::-1]
def rev_list2(l):
return list(reversed(l))
def rev_list3(l):
l.reverse()
return l
Список
l = list(range(1000000))
Сроки 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
Сроки 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
самый быстрый, потому что он разворачивается на месте
list.reverse()
это самый быстрый, но вы штрафуете reversed
(что лучше всего использовать, когда вы не хотите нового list
, просто для итерации существующего list
в обратном порядке без изменения оригинала), и среза (который также позволяет избежать мутации оригинала list
и, как правило, быстрее, чем reversed
когда ввод небольшой). Да, если вам не нужна копия, все, что копирует, является более дорогим, но в большинстве случаев вы не хотите изменять исходное значение.
reversed
все равно проигрываетlist.reverse()
, но, учитывая, что он не изменяет входные данные list
, во многих случаях это лучше. Потеря для reversed
мала (~ 1/6 дольше, чем 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
Использование реверсированного (массива) будет, вероятно, лучшим маршрутом.
>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>> print item
Если вам нужно понять, как можно реализовать это без использования встроенного 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
Это должно занять O (N) время.
Есть несколько хороших ответов, но они разбросаны, и большинство из них не указывают на фундаментальные различия каждого подхода.
В целом, лучше использовать встроенные функции / методы для реверса, как и для любой другой функции. В этом случае они примерно в 2-8 раз быстрее в коротких списках (10 элементов) и в ~ 300 + раз быстрее в длинных списках по сравнению с созданными вручную средствами индексации. Это имеет смысл, поскольку у них есть эксперты, которые их создают, изучают и оптимизируют. Они также менее подвержены дефектам и более склонны обрабатывать края и угловые корпуса.
Также подумайте, хотите ли вы:
object.reverse()
методreversed(object)
создание итератора.object[::-1]
Вот начало моего тестового сценария для описанных методов. Соедините все фрагменты кода в этом ответе вместе, чтобы создать сценарий, который будет запускать все различные способы изменения списка и времени каждого из них (вывод показан в последнем разделе).
from timeit import timeit
from copy import copy
def time_str_ms(t):
return '{0:8.2f} ms'.format(t * 1000)
Если цель состоит в том, чтобы просто изменить порядок элементов в существующем списке, не зацикливая их или не получив копию для работы, используйте <list>.reverse()
функцию. Запустите это непосредственно для объекта списка, и порядок всех элементов будет обратным:
Обратите внимание, что следующее обратит заданную исходную переменную, даже если она вернет обратный список обратно. т.е. вы можете создать копию с помощью этой функции вывода. Как правило, вы не сделаете функцию для этого, но я сделал это, чтобы использовать временной код в конце.
Мы проверим эффективность этих двух способов - сначала просто перевернуть список на месте (изменить исходный список), а затем скопировать список и затем перевернуть его.
def rev_in_place(mylist):
mylist.reverse()
return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()
return a
obj[::-1]
Встроенный метод нарезки индекса позволяет сделать копию части любого проиндексированного объекта.
Общий синтаксис: <object>[first_index:last_index:step]
. Для того, чтобы использовать нарезку , чтобы создать простой перевернутый список, использование: <list>[::-1]
. Оставляя параметр пустым, он устанавливает для них значения по умолчанию первого и последнего элемента объекта (обратный, если размер шага отрицателен).
Индексирование позволяет использовать отрицательные числа, которые отсчитываются от конца индекса объекта в обратном направлении (т. Е. -2 - второй до последнего элемента). Когда размер шага отрицателен, он начинается с последнего элемента и индексируется в обратном направлении на эту сумму. С этим связана некоторая логика начала и конца, которая была оптимизирована.
def rev_slice(mylist):
a = mylist[::-1]
return a
reversed(obj)
функции итератораЕсть reversed(indexed_object)
функция:
Протестируйте как с необработанным итератором, так и создав список из итератора.
def reversed_iterator(mylist):
a = reversed(mylist)
return a
def reversed_with_list(mylist):
a = list(reversed(mylist))
return a
Как покажет время, создание собственных методов индексации - плохая идея. Используйте встроенные методы, если вам не нужно делать что-то действительно нестандартное.
Тем не менее, нет меньшего штрафа с меньшими размерами списка, но когда вы увеличиваете масштаб, он становится огромным. Я уверен, что мой код ниже может быть оптимизирован, но я буду придерживаться встроенных методов.
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
Ниже приведена оставшаяся часть сценария для определения времени каждого метода реверса. Он показывает, что реверсирование на месте obj.reverse()
и создание reversed(obj)
итератора всегда самые быстрые, а использование слайсов - самый быстрый способ создания копии.
Это также доказывает, что вы не пытаетесь создать способ сделать это самостоятельно, если вам не нужно!
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))
Результаты показывают, что масштабирование лучше всего работает с помощью встроенных методов, которые лучше всего подходят для данной задачи. Другими словами, по мере увеличения количества элементов объекта встроенные методы начинают давать гораздо более высокие результаты производительности.
Вам также лучше использовать лучший встроенный метод, который непосредственно достигает того, что вам нужно, чем связывать вещи вместе. то есть нарезка лучше всего, если вам нужна копия перевернутого списка - это быстрее, чем создание списка из reversed()
функции, и быстрее, чем создание копии списка и затем создание на месте obj.reverse()
. Но если любой из этих методов действительно вам нужен, он работает быстрее, но не более чем в два раза быстрее. Между тем - пользовательские, ручные методы могут занимать порядки дольше, особенно с очень большими списками.
Для масштабирования со списком из 1000 элементов reversed(<list>)
вызов функции занимает ~ 30 мс для настройки итератора, обратное изменение на месте занимает всего ~ 55 мс, использование метода среза занимает ~ 210 мс для создания копии полного обращенного списка, но самый быстрый ручной метод, который я сделал, занял ~ 8400 мс !!
С 2 пунктами в списке:
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]
С 10 пунктов в списке:
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]
И с 1000 пунктов в списке:
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
Если вы хотите сохранить элементы обратного списка в какой-либо другой переменной, вы можете использовать revArray = array[::-1]
или revArray = list(reversed(array))
.
Но первый вариант немного быстрее:
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))
Вывод:
Time: 0.00489711761475 s
Time: 0.00609302520752 s
timeit
.
В Python порядок списков также можно манипулировать с помощью sort , упорядочивая переменные в числовом / алфавитном порядке:
print(sorted(my_list))
my_list.sort(), print(my_list)
Вы можете сортировать с флагом "reverse = True" :
print(sorted(my_list, reverse=True))
или
my_list.sort(reverse=True), print(my_list)
Может быть, вы не хотите сортировать значения, а только наоборот. Тогда мы можем сделать это так:
print(list(reversed(my_list)))
** Числа имеют приоритет над алфавитом в порядке листинга. Организация значений Python потрясающая.
Использование логики старой школы для практики на собеседованиях.
Обмен номерами спереди назад. Используя два указателя
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]
Вы также можете использовать побитовое дополнение индекса массива для обратного просмотра массива:
>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]
Что бы вы ни делали, не делайте так.
Другое решение было бы использовать numpy.flip для этого
import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]
Строго говоря, вопрос не в том, как вернуть список в обратном порядке, а в том, как перевернуть список с примером списка имен array
.
Чтобы перевернуть список с именем "array"
использовать array.reverse()
.
Невероятно полезный метод среза, как описано, также может быть использован для реверса списка на месте, определяя список как нарезанную модификацию самого себя, используя array = array[::-1]
.
array[:] = array[::-1]
С минимальным количеством встроенных функций, при условии, что это настройки интервью
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)
Наиболее прямым переводом вашего требования на Python является следующее for
:
for i in xrange(len(array) - 1, -1, -1):
print i, array[i]
Это довольно загадочно, но может быть полезно.
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
//
оператором дивизиона этажа.
Вы всегда можете рассматривать список как стек, просто выталкивая элементы из верхней части стека из заднего конца списка. Таким образом, вы получаете преимущество первой в последней характеристики стека. Конечно, вы потребляете 1-й массив. Мне нравится этот метод в том смысле, что он довольно интуитивно понятен, поскольку вы видите, что один список используется из серверной части, а другой создается из интерфейсной части.
>>> 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
использование
print(reversed(list_name))
Вот способ лениво оценить обратное с помощью генератора :
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
Теперь итерируем так:
for x in reverse([1, 2, 3]):
print(x)
Если вам нужен список:
l = list(reverse([1, 2, 3]))
Есть 3 способа получить обратный список:
Метод нарезки 1: reversed_array = array[-1::-1]
Метод нарезки 2:
reversed_array2 = array[::-1]
Используя встроенную функцию: reversed_array = array.reverse()
Третья функция фактически перевернула список объектов на месте. Это означает, что копия первичных данных не поддерживается. Это хороший подход, если вы не хотите поддерживать старую версию. Но, похоже, это не решение проблемы, если вы хотите использовать нетронутую и обратную версию.