Câu trả lời:
Bạn có thể sử dụng reversed
chức năng này như:
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
Lưu ý rằng reversed(...)
không trả về một danh sách. Bạn có thể nhận được một danh sách đảo ngược bằng cách sử dụng list(reversed(array))
.
reverse
mặc dù có thể nhanh hơn, nếu bạn không cần phải đưa vào danh sách sau đó.
reversed()
thay vì cắt lát? Đọc Zen của Python, quy tắc số 7: Tính dễ đọc!
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
Cú pháp lát mở rộng được giải thích tốt trong Python Mục nhập mới để phát hành2.3.5
Theo yêu cầu đặc biệt trong một bình luận, đây là tài liệu lát mới nhất .
reversed
trả về một listreverseiterator
đối tượng (Python 2.7.x), sau đó phải được lặp qua - cắt ngược trả về một danh sách đảo ngược / tuple / str (tùy thuộc vào những gì bạn đang cắt). @Einar Petersen đang đảo ngược một chuỗi, vì vậy đầu ra là chính xác. Hãy thử: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]
Hoặc là
>>> L[::-1]
[40, 20, 10, 0]
L=L[::-1]
thực sự đảo ngược danh sách nếu không bạn chỉ trả lại các giá trị theo chiều ngược lại
b = l[-n:] b.reverse() l = b + l[:len(l) - n]
Tôi nghĩ rằng cách tốt nhất để đảo ngược danh sách trong Python là làm:
a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]
Công việc đã hoàn thành và bây giờ bạn có một danh sách đảo ngược.
Để đảo ngược cùng một danh sách sử dụng:
array.reverse()
Để gán danh sách đảo ngược vào một số danh sách khác, hãy sử dụng:
newArray = array[::-1]
Sử dụng cắt, ví dụ mảng = mảng [:: - 1], là một thủ thuật gọn gàng và rất Pythonic, nhưng có thể hơi mơ hồ đối với người mới. Sử dụng phương thức Reverse () là một cách tốt để mã hóa hàng ngày vì nó dễ đọc.
Tuy nhiên, nếu bạn cần đảo ngược một danh sách tại chỗ như trong một câu hỏi phỏng vấn, bạn có thể sẽ không thể sử dụng các phương thức được xây dựng như thế này. Người phỏng vấn sẽ xem xét cách bạn tiếp cận vấn đề thay vì độ sâu của kiến thức Python, một phương pháp thuật toán là bắt buộc. Ví dụ sau đây, sử dụng trao đổi cổ điển, có thể là một cách để làm điều đó: -
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]
Lưu ý rằng điều này sẽ không hoạt động trên Tuples hoặc chuỗi chuỗi, bởi vì chuỗi và tuple là bất biến, tức là bạn không thể ghi vào chúng để thay đổi các phần tử.
lst[hiindex], lst[i] = lst[i], lst[hiindex]
, tôi nghĩ rằng ... ;-)
array[::-1]
hoàn toàn dễ đọc và hoàn toàn rõ ràng nếu bạn biết Python . "Có thể đọc" không có nghĩa là "một người chưa bao giờ sử dụng Python cắt lát trước đây phải có khả năng đọc nó"; các [::-1]
lát đảo ngược là một thành ngữ ridiculously chung bằng Python (bạn sẽ gặp nó trong mã tất cả các thời gian tồn tại), và nó hoàn toàn có thể đọc được nếu bạn thường xuyên sử dụng Python . Chắc chắn, first10 = []
, for i in range(10): first10.append(array[i])
rõ ràng và rõ ràng, nhưng điều đó không làm cho nó tốt hơn first10 = array[:10]
.
Tôi thấy (trái với một số gợi ý khác) đó l.reverse()
là cách nhanh nhất để đảo ngược một danh sách dài trong Python 3 và 2. Tôi rất muốn biết liệu những người khác có thể sao chép các thời gian này hay không.
l[::-1]
có lẽ chậm hơn vì nó sao chép danh sách trước khi đảo ngược nó. Thêm list()
cuộc gọi xung quanh trình vòng lặp được thực hiện bằng cách reversed(l)
thêm một số chi phí. Tất nhiên nếu bạn muốn có một bản sao của danh sách hoặc một trình vòng lặp thì hãy sử dụng các phương thức tương ứng đó, nhưng nếu bạn muốn đảo ngược danh sách thì l.reverse()
dường như là cách nhanh nhất.
Chức năng
def rev_list1(l):
return l[::-1]
def rev_list2(l):
return list(reversed(l))
def rev_list3(l):
l.reverse()
return l
Danh sách
l = list(range(1000000))
Định thời 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
Định thời 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
là nhanh nhất, bởi vì nó đảo ngược tại chỗ
list.reverse()
là nhanh nhất, nhưng bạn đang xử phạt reversed
(được sử dụng tốt nhất khi bạn không muốn một cái mới list
, chỉ để lặp lại một list
thứ tự hiện có theo thứ tự ngược lại mà không làm thay đổi bản gốc) và lát cắt (cũng tránh làm biến đổi bản gốc list
và thường nhanh hơn reversed
khi đầu vào nhỏ). Có, nếu bạn không cần bản sao, bất cứ thứ gì bản sao đắt hơn, nhưng rất nhiều thời gian, bạn không muốn làm thay đổi giá trị ban đầu.
reversed
vẫn thualist.reverse()
dù vậy, nhưng nếu nó không làm thay đổi đầu vào list
, thì tốt hơn trong nhiều trường hợp. Mất mát reversed
là nhỏ (~ 1/6 dài hơn list.reverse()
).
Sử dụng đảo ngược (mảng) sẽ là con đường tốt nhất có khả năng.
>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>> print item
Nếu bạn cần hiểu làm thế nào có thể thực hiện điều này mà không cần sử dụng tích hợp 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
Điều này sẽ mất thời gian O (N).
Có một số câu trả lời hay, nhưng trải rộng ra và hầu hết không chỉ ra sự khác biệt cơ bản của từng phương pháp.
Nhìn chung, tốt hơn là sử dụng các hàm / phương thức tích hợp để đảo ngược, như với bất kỳ chức năng nào. Trong trường hợp này, chúng nhanh hơn khoảng 2 đến 8 lần trên các danh sách ngắn (10 mục) và nhanh hơn ~ 300 lần trên các danh sách dài so với các phương tiện lập chỉ mục được tạo thủ công. Điều này có ý nghĩa khi họ có các chuyên gia tạo ra chúng, xem xét kỹ lưỡng và tối ưu hóa. Họ cũng ít bị khuyết tật và có nhiều khả năng xử lý các trường hợp cạnh và góc.
Cũng xem xét liệu bạn có muốn:
object.reverse()
phương phápreversed(object)
tạo iteratorobject[::-1]
Đây là sự khởi đầu của kịch bản thử nghiệm của tôi cho các phương thức được đề cập. Đặt tất cả các đoạn mã trong câu trả lời này cùng nhau để tạo một tập lệnh sẽ chạy tất cả các cách khác nhau để đảo ngược danh sách và thời gian mỗi danh sách (đầu ra được hiển thị trong phần cuối).
from timeit import timeit
from copy import copy
def time_str_ms(t):
return '{0:8.2f} ms'.format(t * 1000)
Nếu mục tiêu chỉ là đảo ngược thứ tự của các mục trong danh sách hiện có, mà không lặp qua chúng hoặc nhận một bản sao để làm việc, hãy sử dụng <list>.reverse()
chức năng. Chạy nó trực tiếp trên một đối tượng danh sách và thứ tự của tất cả các mục sẽ được đảo ngược:
Lưu ý rằng sau đây sẽ đảo ngược biến ban đầu được đưa ra, mặc dù nó cũng trả lại danh sách đảo ngược. tức là bạn có thể tạo một bản sao bằng cách sử dụng chức năng đầu ra này. Thông thường, bạn sẽ không tạo ra một chức năng cho việc này, nhưng tôi đã làm như vậy để sử dụng mã thời gian ở cuối.
Chúng tôi sẽ kiểm tra hiệu suất của hai cách này - trước tiên chỉ cần đảo ngược danh sách tại chỗ (thay đổi danh sách ban đầu), sau đó sao chép danh sách và đảo ngược danh sách sau đó.
def rev_in_place(mylist):
mylist.reverse()
return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()
return a
obj[::-1]
Phương pháp cắt chỉ mục tích hợp cho phép bạn tạo một bản sao của một phần của bất kỳ đối tượng được lập chỉ mục nào.
Cú pháp chung là : <object>[first_index:last_index:step]
. Để khai thác cắt để tạo một danh sách đảo ngược đơn giản, sử dụng : <list>[::-1]
. Khi để trống một tùy chọn, nó đặt chúng thành mặc định của phần tử đầu tiên và cuối cùng của đối tượng (đảo ngược nếu kích thước bước là âm).
Lập chỉ mục cho phép một người sử dụng các số âm, tính từ cuối chỉ mục của đối tượng trở lại (tức là -2 là mục thứ hai đến mục cuối cùng). Khi kích thước bước âm, nó sẽ bắt đầu với mục cuối cùng và chỉ mục lùi theo số tiền đó. Có một số logic bắt đầu liên quan đến điều này đã được tối ưu hóa.
def rev_slice(mylist):
a = mylist[::-1]
return a
reversed(obj)
chức năng lặpCó một reversed(indexed_object)
chức năng:
Kiểm tra với cả một trình vòng lặp thô và tạo một danh sách từ trình vòng lặp.
def reversed_iterator(mylist):
a = reversed(mylist)
return a
def reversed_with_list(mylist):
a = list(reversed(mylist))
return a
Vì thời gian sẽ hiển thị, tạo các phương pháp lập chỉ mục của riêng bạn là một ý tưởng tồi. Sử dụng các phương thức tích hợp trừ khi bạn cần làm một cái gì đó thực sự tùy chỉnh.
Điều đó nói rằng, không có một hình phạt lớn với kích thước danh sách nhỏ hơn, nhưng khi bạn tăng quy mô hình phạt sẽ trở nên rất lớn. Tôi chắc chắn mã của tôi dưới đây có thể được tối ưu hóa, nhưng tôi sẽ sử dụng các phương thức tích hợp sẵn.
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
Sau đây là phần còn lại của kịch bản theo thời gian mỗi phương pháp đảo ngược. Nó cho thấy việc đảo ngược tại chỗ với obj.reverse()
và tạo reversed(obj)
iterator luôn là nhanh nhất, trong khi sử dụng các lát cắt là cách nhanh nhất để tạo một bản sao.
Nó cũng chứng tỏ không cố gắng tự tạo ra một cách làm trừ khi bạn phải làm!
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))
Kết quả cho thấy tỷ lệ hoạt động tốt nhất với các phương thức tích hợp phù hợp nhất cho một nhiệm vụ nhất định. Nói cách khác, khi số lượng phần tử đối tượng tăng lên, các phương thức tích hợp bắt đầu có kết quả hiệu suất vượt trội hơn nhiều.
Bạn cũng nên sử dụng phương pháp tích hợp tốt nhất trực tiếp đạt được những gì bạn cần hơn là kết hợp mọi thứ lại với nhau. tức là cắt lát là tốt nhất nếu bạn cần một bản sao của danh sách đảo ngược - nó nhanh hơn việc tạo một danh sách từ reversed()
hàm và nhanh hơn là tạo một bản sao của danh sách và sau đó thực hiện tại chỗ obj.reverse()
. Nhưng nếu một trong những phương pháp đó thực sự là tất cả những gì bạn cần, chúng sẽ nhanh hơn, nhưng không bao giờ nhiều hơn gấp đôi tốc độ. Trong khi đó - các phương thức thủ công, tùy chỉnh có thể nhận các đơn đặt hàng có độ lớn lâu hơn, đặc biệt là với các danh sách rất lớn.
Để chia tỷ lệ, với danh sách 1000 mục, lệnh reversed(<list>)
gọi hàm mất ~ 30 ms để thiết lập trình lặp, việc đảo ngược tại chỗ chỉ mất ~ 55 ms, sử dụng phương thức lát mất ~ 210 ms để tạo một bản sao của danh sách đảo ngược hoàn toàn, nhưng phương pháp thủ công nhanh nhất tôi đã thực hiện mất ~ 8400 ms !!
Với 2 mục trong danh sách:
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]
Với 10 mục trong danh sách:
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]
Và với 1000 mặt hàng trong danh sách:
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
Nếu bạn muốn lưu trữ các phần tử của danh sách đảo ngược trong một số biến khác, thì bạn có thể sử dụng revArray = array[::-1]
hoặc revArray = list(reversed(array))
.
Nhưng biến thể đầu tiên nhanh hơn một chút:
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))
Đầu ra:
Time: 0.00489711761475 s
Time: 0.00609302520752 s
timeit
.
Trong Python, thứ tự của danh sách cũng có thể được thao tác với sắp xếp , sắp xếp các biến của bạn theo thứ tự số / bảng chữ cái:
print(sorted(my_list))
my_list.sort(), print(my_list)
Bạn có thể sắp xếp với cờ "Reverse = True" :
print(sorted(my_list, reverse=True))
hoặc là
my_list.sort(reverse=True), print(my_list)
Có thể bạn không muốn sắp xếp các giá trị mà chỉ đảo ngược các giá trị. Sau đó chúng ta có thể làm điều đó như thế này:
print(list(reversed(my_list)))
** Số được ưu tiên hơn bảng chữ cái theo thứ tự liệt kê. Tổ chức của các giá trị Python là tuyệt vời.
Sử dụng một số logic trường học cũ để thực hành cho các cuộc phỏng vấn.
Hoán đổi số trước ra sau. Sử dụng hai con trỏ
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]
Bạn cũng có thể sử dụng phần bù bitwise của chỉ mục mảng để chuyển qua mảng theo chiều ngược lại:
>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]
Dù bạn làm gì, đừng làm theo cách này.
Một giải pháp khác là sử dụng numpy.flip cho việc này
import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]
Nói một cách chính xác, câu hỏi không phải là làm thế nào để trả về một danh sách ngược mà là làm thế nào để đảo ngược một danh sách với một tên danh sách ví dụ array
.
Để đảo ngược một danh sách có tên "array"
sử dụng array.reverse()
.
Phương pháp lát cực kỳ hữu ích như được mô tả cũng có thể được sử dụng để đảo ngược danh sách tại chỗ bằng cách xác định danh sách là một sửa đổi được cắt lát của chính nó bằng cách sử dụng 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
Với số lượng chức năng tích hợp tối thiểu, giả sử đó là cài đặt phỏng vấn
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)
Bản dịch trực tiếp nhất về yêu cầu của bạn sang Python là for
tuyên bố này :
for i in xrange(len(array) - 1, -1, -1):
print i, array[i]
Điều này khá khó hiểu nhưng có thể hữu ích.
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
//
toán tử phân chia sàn.
Bạn luôn có thể coi danh sách như một ngăn xếp chỉ cần bật các phần tử ra khỏi đầu ngăn xếp từ cuối danh sách. Bằng cách đó, bạn tận dụng lợi thế đầu tiên trong các đặc điểm cuối cùng của ngăn xếp. Tất nhiên bạn đang tiêu thụ mảng 1. Tôi thích phương pháp này ở chỗ nó khá trực quan ở chỗ bạn thấy một danh sách được sử dụng từ mặt sau trong khi danh sách kia đang được xây dựng từ mặt trước.
>>> 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
sử dụng
print(reversed(list_name))
Đây là một cách để đánh giá ngược lại bằng cách sử dụng một trình tạo :
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
Bây giờ lặp lại như thế này:
for x in reverse([1, 2, 3]):
print(x)
Nếu bạn cần một danh sách:
l = list(reverse([1, 2, 3]))
Có 3 phương pháp để có được danh sách đảo ngược:
Phương pháp cắt lát 1: reversed_array = array[-1::-1]
Phương pháp cắt lát 2:
reversed_array2 = array[::-1]
Sử dụng hàm dựng sẵn: reversed_array = array.reverse()
Hàm thứ ba thực sự đảo ngược đối tượng danh sách tại chỗ. Điều đó có nghĩa là không có bản sao dữ liệu nguyên sơ được duy trì. Đây là một cách tiếp cận tốt nếu bạn không muốn duy trì phiên bản cũ. Nhưng dường như không phải là một giải pháp nếu bạn muốn phiên bản nguyên sơ và đảo ngược.