Відповіді:
Ви можете скористатися цією reversed
функцією як:
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
Зверніть увагу, що reversed(...)
список не повертає. Ви можете отримати зворотний список за допомогою list(reversed(array))
.
reverse
можливо, буде швидше, якщо вам не потрібно буде додавати їх до списку згодом.
reversed()
замість нарізки? Прочитайте Дзен Пітона, правило №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]
Для зміни стороннього списку використовуйте:
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()
).
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) час.
Якщо ви хочете зберегти елементи зворотного списку в якійсь іншій змінній, тоді ви можете використовувати 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 впорядкованість списків теж може маніпулювати сортуванням , упорядковуючи свої змінні в числовому / алфавітному порядку:
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 є приголомшливою.
Є кілька хороших відповідей, але вони розкриті, і більшість не вказує на принципові відмінності кожного підходу.
В цілому, краще використовувати вбудовані функції / методи для зворотного зв'язку, як і майже про будь-яку функцію. У цьому випадку вони приблизно в 2 - 8 разів швидші в коротких списках (10 позицій), а в довгих списках - до ~ 300 + в рази швидші порівняно з засобами індексації, створеними вручну. Це має сенс, оскільки у них є фахівці, які їх створюють, перевіряють та оптимізують. Вони також менш схильні до дефектів і швидше обробляють кромки і куточки.
Також врахуйте, чи бажаєте ви:
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 с. найшвидший ручний метод, який я зробив, зайняв ~ 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
Використання старої шкільної логіки для практики інтерв'ю.
Поміняючи номери спереду назад. Використання двох покажчиків
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()
Третя функція фактично перевернула об'єкт списку на місці. Це означає, що не зберігається копія незайманих даних. Це хороший підхід, якщо ви не хочете підтримувати стару версію. Але це, здається, не є рішенням, якщо ви хочете незайману і перевернуту версію.