ฉันจะย้อนกลับรายการใน Python ได้อย่างไร


1037

ฉันจะทำสิ่งต่อไปนี้ใน Python ได้อย่างไร

array = [0, 10, 20, 40]
for (i = array.length() - 1; i >= 0; i--)

ฉันต้องมีองค์ประกอบของอาร์เรย์ แต่ตั้งแต่ต้นจนจบ

คำตอบ:


1320

คุณสามารถใช้ประโยชน์จากreversedฟังก์ชั่นนี้เป็น:

>>> array=[0,10,20,40]
>>> for i in reversed(array):
...     print(i)

โปรดทราบว่าreversed(...)จะไม่ส่งคืนรายการ list(reversed(array))คุณจะได้รับรายการโอนกลับใช้


193
คุณไม่สามารถใช้: อาร์เรย์ [:: - 1]
kdlannoy

134
@kdlannoy ตามหน้าที่เชื่อมโยงกับคำตอบ "เมื่อเปรียบเทียบกับการแบ่งส่วนแบบขยายเช่นช่วง (1,4) [:: - 1] การกลับด้าน () นั้นง่ายต่อการอ่านรันเร็วกว่าและใช้หน่วยความจำน้อยกว่ามาก "
จิมโอลด์ฟิลด์

5
เมื่อฉันทดสอบการแบ่งส่วนนี้มันเร็วกว่าสองเท่า (เมื่อย้อนกลับรายการองค์ประกอบ 10k และสร้างรายการจากมัน) ฉันไม่ได้ทดสอบการใช้หน่วยความจำ reverseอาจจะเร็วกว่าหากคุณไม่จำเป็นต้องส่งรายการต่อไป
Dakkaron

5
น่าสังเกตว่านี่ไม่เหมือนกับ reverse ([1,2,3]), nb the 'd' ณ สิ้น ... ซึ่งเป็นหนึ่งในคำตอบอื่น ๆ ด้านล่างซึ่งทำหน้าที่นี้แทน ตัววนซ้ำ
ลูเซียโน

14
ทำไมต้องใช้reversed()แทนการหั่น? อ่าน Zen of Python กฎข้อที่ 7: จำนวนที่อ่านได้!
kramer65

1247
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]

ไวยากรณ์ของส่วนขยายเพิ่มเติมอธิบายได้ดีใน Python มีอะไรใหม่ที่เป็นประโยชน์2.3.5

โดยคำขอพิเศษในความคิดเห็นนี่เป็นเอกสารชิ้นล่าสุด


12
มันใช้งานได้สำหรับรายการที่ไม่สามารถทำงานร่วมกันได้ ข้อเสียคือมันไม่ได้อยู่ในสถานที่
สวิส

6
@ มันส่งคืนชิ้นดังนั้นอย่าเปลี่ยนเนื้อหาของรายการจริง
fortran

12
@lunixbochs ที่คืนค่าเป็นตัววนซ้ำและไม่ใช่รายการใน Python 3
Swiss

2
เว้นแต่จะถูกห่อหุ้มอย่างเป็นธรรมชาติภายในอาเรย์
Einar Petersen

2
ฉันเห็นด้วยกับ @Swiss +1 เนื่องจากคำถามคือฉันต้องมีองค์ประกอบของอาร์เรย์ แต่ตั้งแต่ต้นจนจบ - reversedส่งคืนlistreverseiteratorวัตถุ (Python 2.7.x) ซึ่งจะต้องทำซ้ำผ่าน - การแบ่งส่วนกลับส่งคืนรายการ / tuple / 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]
แอรอนนิวตัน

368
>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]

หรือ

>>> L[::-1]
[40, 20, 10, 0]

61
[start: stop: step] ดังนั้น step คือ -1
papalagi

37
รายละเอียด: รายการแรกปรับเปลี่ยนในสถานที่รายการที่สองเพิ่งส่งคืนรายการที่กลับรายการใหม่ แต่ไม่ได้แก้ไขรายการเดิม
franzlorenzon

7
ตัวอย่างที่สองควรL=L[::-1]กลับรายการจริงมิฉะนั้นคุณจะคืนค่าในสิ่งที่ตรงกันข้าม
robertmoggach

สมมุติว่าถ้าฉันมี l = [1,2,3,4,5,6] และ n = 2 ผลลัพธ์จะต้องเป็น [6,5,1,2,3,4] เราจะทำสิ่งนี้ได้อย่างไร
Atul Jain

คุณสามารถทำได้:b = l[-n:] b.reverse() l = b + l[:len(l) - n]
Shoaib Shakeel

56

นี่คือการทำซ้ำรายการ:

L = [0,10,20,40]
p = L[::-1]  #  Here p will be having reversed list

นี่คือการย้อนกลับรายการในสถานที่:

L.reverse() # Here L will be reversed in-place (no new list made)

51

ฉันคิดว่าวิธีที่ดีที่สุดในการย้อนรายการใน Python ก็คือ:

a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]

งานเสร็จแล้วและตอนนี้คุณมีรายการที่กลับรายการ


27

สำหรับการกลับรายการเดียวกันให้ใช้:

array.reverse()

ในการกำหนดรายการที่กลับรายการให้เป็นรายการอื่นให้ใช้:

newArray = array[::-1] 

27

การใช้การแบ่งตัวอย่างเช่น array = array [:: - 1] เป็นกลอุบายที่ประณีตและ Pythonic มาก แต่อาจคลุมเครือเล็กน้อยสำหรับมือใหม่ การใช้วิธี 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]

โปรดทราบว่าสิ่งนี้จะไม่ทำงานบน Tuples หรือลำดับสตริงเนื่องจากสตริงและ tuples นั้นไม่เปลี่ยนรูปนั่นคือคุณไม่สามารถเขียนลงในพวกมันเพื่อเปลี่ยนองค์ประกอบ


9
การสลับแบบคลาสสิคสามารถทำได้ผ่านทางlst[hiindex], lst[i] = lst[i], lst[hiindex]ฉันคิดว่า ... ;-)
Samoth

@Samoth ไวยากรณ์นั้นไม่ชัดเจนและพฤติกรรมนั้นไม่ชัดเจน ขั้นตอนที่แตกต่างทำให้รู้สึกมากขึ้น
แอนโธนี

ทำไมผู้คนถึงบอกว่าสิ่งต่าง ๆ เช่นอาเรย์ [:: - 1] เป็นไพ ธ อน หลามเซนสอนเราว่าชัดเจนดีกว่าการนับโดยนัยและการอ่านได้ สิ่งที่ไม่ชัดเจนและสามารถอ่านได้ทั้งหมด
k4ppa

1
@ k4ppa: array[::-1]เป็นอย่างดีและสามารถอ่านได้อย่างชัดเจนอย่างสมบูรณ์แบบถ้าคุณรู้ว่างูหลาม "อ่านได้" ไม่ได้หมายถึง "คนที่ไม่เคยใช้ Python slicing มาก่อนต้องสามารถอ่านได้"; [::-1]ชิ้นย้อนกลับเป็นสำนวนขันในหลาม (คุณจะพบในรหัสทุกครั้งที่มีอยู่) และก็สามารถอ่านได้อย่างสมบูรณ์แบบถ้าคุณใช้เป็นประจำหลาม แน่นอนว่าfirst10 = [], for i in range(10): first10.append(array[i])มีความชัดเจนและชัดเจน first10 = array[:10]แต่นั่นไม่ได้ทำให้มันได้ดีกว่า
ShadowRanger

19

ฉันพบ (ตรงกันข้ามกับคำแนะนำอื่น ๆ ) ที่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

4
list.reverseเป็นวิธีที่เร็วที่สุดเพราะมันกลับด้านในสถานที่
warvariuc

คุณถูกต้องlist.reverse()เร็วที่สุด แต่คุณกำลังลงโทษreversed(ซึ่งใช้ดีที่สุดเมื่อคุณไม่ต้องการใหม่listเพียงทำซ้ำที่มีอยู่listในลำดับย้อนกลับโดยไม่ต้องกลายพันธุ์เดิม) และชิ้น (ซึ่งยังหลีกเลี่ยงการกลายพันธุ์เดิมlistและโดยทั่วไปจะเร็วกว่าreversedเมื่ออินพุตมีขนาดเล็ก) ใช่หากคุณไม่ต้องการสำเนาสิ่งใดก็ตามที่สำเนามีราคาแพงกว่า แต่บ่อยครั้งคุณไม่ต้องการเปลี่ยนค่าดั้งเดิม
ShadowRanger

ดูเหมือนว่าจะreversed ยังคงเป็นlist.reverse()เช่นนั้น แต่เนื่องจากไม่ได้ทำให้อินพุตกลายพันธุ์listดีกว่าในหลายกรณี การสูญเสียสำหรับreversedมีขนาดเล็ก (~ 1 / 6th นานกว่าlist.reverse())
ShadowRanger

16
for x in array[::-1]:
    do stuff

วิธีการแบ่งส่วนนี้ไม่สามารถอ่านได้มาก วิธี Pythonic จะใช้วิธี reverse () ;-)
SimonM

@SimonM reverse () ง่ายต่อการเข้าใจได้อย่างรวดเร็ว
สวิส



7

การใช้ reverse (array) จะเป็นเส้นทางที่ดีที่สุด

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


หาวิธีทำโดยไม่ใช้ฟังก์ชั่นย้อนกลับ ขอบคุณ
เบอร์นาร์ด 'เบต้าเบอร์ลิน' ปาราห์

หรือเพื่อย้อนกลับในการใช้งาน list = list.reverse ()
SimonM

6

สรุปวิธีการที่มีคำอธิบายและผลลัพธ์การกำหนดเวลา

มีคำตอบที่ดีหลายข้อ แต่ส่วนใหญ่แล้วก็ไม่ได้บอกถึงความแตกต่างพื้นฐานของแต่ละวิธี

โดยรวมจะดีกว่าถ้าใช้ฟังก์ชั่น / วิธีการในตัวเพื่อย้อนกลับเช่นเดียวกับฟังก์ชั่นใด ๆ ในกรณีนี้พวกเขาจะเร็วขึ้นประมาณ 2 ถึง 8 เท่าในรายการสั้น ๆ (10 รายการ) และเร็วกว่า ~ 300 + เท่าสำหรับรายการแบบยาวเมื่อเปรียบเทียบกับการสร้างดัชนีด้วยตนเอง สิ่งนี้มีเหตุผลเนื่องจากมีผู้เชี่ยวชาญในการสร้างการพิจารณาและการเพิ่มประสิทธิภาพ นอกจากนี้ยังมีแนวโน้มที่จะเกิดข้อบกพร่องน้อยกว่าและมีแนวโน้มที่จะจัดการกับกล่องแบบขอบและมุมมากขึ้น

พิจารณาด้วยว่าคุณต้องการ:

  1. ย้อนกลับรายการที่มีอยู่ในสถานที่
    • ทางออกที่ดีที่สุดคือobject.reverse()วิธีการ
  2. สร้างตัววนซ้ำของการย้อนกลับของรายการ (เพราะคุณจะป้อนมันไปยัง for-loop, generator, ฯลฯ )
    • ทางออกที่ดีที่สุดคือการreversed(object)สร้างตัววนซ้ำ
  3. หรือสร้างสำเนาที่สมบูรณ์ซึ่งอยู่ในลำดับย้อนกลับ
    • ทางออกที่ดีที่สุดคือการใช้ชิ้นส่วนที่มีขนาดขั้นตอนที่ -1: object[::-1]

สคริปต์ทดสอบ

นี่คือจุดเริ่มต้นของสคริปต์ทดสอบของฉันสำหรับวิธีการที่ครอบคลุม วางข้อมูลโค้ดทั้งหมดไว้ในคำตอบนี้ร่วมกันเพื่อสร้างสคริปต์ที่จะเรียกใช้วิธีต่างๆในการย้อนกลับรายการและเวลาแต่ละรายการ (ผลลัพธ์ที่แสดงในส่วนสุดท้าย)

from timeit import timeit
from copy import copy

def time_str_ms(t):
    return '{0:8.2f} ms'.format(t * 1000)

วิธีที่ 1: ย้อนกลับด้วย obj.reverse ()

หากเป้าหมายเป็นเพียงการย้อนกลับลำดับของรายการในรายการที่มีอยู่โดยไม่ต้องวนซ้ำพวกเขาหรือรับสำเนาเพื่อใช้งานให้ใช้<list>.reverse()ฟังก์ชัน เรียกใช้สิ่งนี้โดยตรงบนรายการวัตถุและลำดับของรายการทั้งหมดจะถูกย้อนกลับ:

โปรดทราบว่าข้อมูลต่อไปนี้จะย้อนกลับตัวแปรดั้งเดิมที่กำหนดแม้ว่าจะส่งกลับรายการที่ย้อนกลับด้วยเช่นกัน เช่นคุณสามารถสร้างสำเนาโดยใช้ฟังก์ชั่นการส่งออกนี้ โดยทั่วไปแล้วคุณจะไม่ทำฟังก์ชั่นสำหรับสิ่งนี้ แต่ฉันทำเช่นนั้นเพื่อใช้รหัสเวลาในตอนท้าย

เราจะทดสอบประสิทธิภาพของสองวิธีนี้ก่อนอื่นเพียงแค่ย้อนกลับรายการในสถานที่ (เปลี่ยนรายการดั้งเดิม) จากนั้นคัดลอกรายการและย้อนกลับหลังจากนั้น

def rev_in_place(mylist):
    mylist.reverse()
    return mylist

def rev_copy_reverse(mylist):
    a = copy(mylist)
    a.reverse()
    return a

วิธีที่ 2: ย้อนกลับรายการโดยใช้ชิ้น obj[::-1]

วิธีการแบ่งส่วนดัชนีในตัวช่วยให้คุณสามารถทำสำเนาส่วนหนึ่งของวัตถุดัชนีใด ๆ

  • ไม่ส่งผลกระทบต่อวัตถุดั้งเดิม
  • มันสร้างรายการทั้งหมดไม่ใช่ตัววนซ้ำ

<object>[first_index:last_index:step]ไวยากรณ์ทั่วไปคือ <list>[::-1]เพื่อใช้ประโยชน์ในการสร้างหั่นง่ายรายการกลับใช้งาน: เมื่อปล่อยให้ตัวเลือกว่างเปล่ามันจะตั้งค่าให้เป็นค่าเริ่มต้นขององค์ประกอบแรกและสุดท้ายของวัตถุ (กลับด้านถ้าขนาดขั้นตอนเป็นลบ)

การจัดทำดัชนีอนุญาตให้หนึ่งใช้ตัวเลขติดลบซึ่งนับจากจุดสิ้นสุดของดัชนีของวัตถุไปข้างหลัง (เช่น -2 คือรายการที่สองถึงรายการสุดท้าย) เมื่อขนาดขั้นตอนเป็นลบมันจะเริ่มต้นด้วยรายการสุดท้ายและจัดทำดัชนีย้อนกลับตามจำนวนนั้น มีตรรกะเริ่มต้นบางส่วนที่เกี่ยวข้องกับสิ่งนี้ซึ่งได้รับการปรับให้เหมาะสม

def rev_slice(mylist):
    a = mylist[::-1]
    return a

วิธีที่ 3: ย้อนกลับรายการด้วยการ 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

วิธีที่ 4: รายการย้อนกลับที่มีการจัดทำดัชนีเอง / ด้วยตนเอง

ตามเวลาที่กำหนดการสร้างวิธีการจัดทำดัชนีของคุณเองเป็นความคิดที่ไม่ดี ใช้วิธีการในตัวเว้นแต่ว่าคุณจะต้องทำสิ่งที่กำหนดเองจริงๆ

ที่กล่าวว่าไม่มีโทษมากกับรายการขนาดเล็ก แต่เมื่อคุณเพิ่มการลงโทษจะยิ่งใหญ่ ฉันแน่ใจว่าโค้ดด้านล่างของฉันสามารถเพิ่มประสิทธิภาพได้ แต่ฉันจะใช้วิธีการในตัว

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

ผลการกำหนดเวลา

ผลลัพธ์แสดงให้เห็นว่าการปรับสเกลทำงานได้ดีที่สุดด้วยวิธีการในตัวที่เหมาะสมที่สุดสำหรับงานที่กำหนด กล่าวอีกนัยหนึ่งเมื่อจำนวนองค์ประกอบของวัตถุเพิ่มขึ้นวิธีการในตัวจะเริ่มให้ผลลัพธ์ที่เหนือกว่า

นอกจากนี้คุณยังดีกว่าโดยใช้วิธีการในตัวที่ดีที่สุดที่บรรลุสิ่งที่คุณต้องการโดยตรงกว่าการรวมสิ่งต่างๆเข้าด้วยกัน ie การแบ่งส่วนดีที่สุดถ้าคุณต้องการสำเนาของรายการที่กลับรายการ - เร็วกว่าการสร้างรายการจากreversed()ฟังก์ชันและเร็วกว่าการทำสำเนารายการและทำในสถานที่obj.reverse()ฟังก์ชั่นและเร็วกว่าการทำสำเนาของรายการและจากนั้นทำในสถานที่แต่ถ้าวิธีใดวิธีหนึ่งเหล่านี้เป็นสิ่งที่คุณต้องการจริงๆพวกเขาก็จะเร็วกว่า แต่ก็ไม่ได้เพิ่มความเร็วเป็นสองเท่าเลย ในขณะเดียวกัน - กำหนดเองวิธีการแมนนวลสามารถทำให้ขนาดของคำสั่งยาวขึ้นโดยเฉพาะกับรายการที่มีขนาดใหญ่มาก

สำหรับการไต่สวนด้วยรายการ 1,000 รายการการreversed(<list>)เรียกใช้ฟังก์ชันใช้เวลา ~ 30 ms ในการตั้งค่าตัววนซ้ำการย้อนกลับในตำแหน่งใช้เวลาเพียง ~ 55 ms โดยใช้วิธี slice ใช้เวลา ~ 210 ms เพื่อสร้างสำเนาของรายการย้อนกลับทั้งหมด แต่ วิธีการด้วยตนเองที่เร็วที่สุดที่ฉันทำใช้เวลา ~ 8400 ms !!

ด้วย 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]

และมี 1,000 รายการในรายการ:

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

5

หากคุณต้องการเก็บองค์ประกอบของรายการย้อนกลับไปในตัวแปรอื่น ๆ บางแล้วคุณสามารถใช้หรือ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

2
timeitครั้งต่อไปที่คุณอาจต้องการที่จะใช้
grooveplex

5

ค่านิยมขององค์กร:

ใน 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 นั้นยอดเยี่ยมมาก


4

ใช้ตรรกะบางอย่าง

การใช้ตรรกะของโรงเรียนเก่าเพื่อฝึกฝนการสัมภาษณ์

สลับหมายเลขหน้าไปหลัง ใช้สองพอยน์เตอร์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]

หากเราแบ่งรายชื่อออกเป็นสองส่วนและสลับอันดับแรกกับดัชนีสุดท้ายและความซับซ้อนของเวลาจะมีประสิทธิภาพมากกว่าตัวอย่างที่แสดง
อิสราเอล Manzo

3

นอกจากนี้คุณยังสามารถใช้บิตเรทของดัชนีอาเรย์เพื่อย้อนกลับอาร์เรย์ได้:

>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]

ไม่ว่าคุณจะทำอะไรอย่าทำอย่างนี้



3

วิธีแก้ปัญหาอื่นก็คือใช้numpy.flipสำหรับสิ่งนี้

import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]

2

พูดอย่างเคร่งครัดคำถามไม่ได้วิธีการกลับรายการในสิ่งที่ตรงกันข้าม arrayแต่วิธีการกลับรายการที่มีชื่อรายการตัวอย่างเช่น

ที่จะกลับรายการตั้งชื่อใช้งาน"array"array.reverse()

วิธีชิ้นที่มีประโยชน์อย่างไม่น่าเชื่อตามที่อธิบายไว้นอกจากนี้ยังสามารถใช้ในการกลับรายการในสถานที่โดยการกำหนดรายการเช่นการปรับเปลี่ยนหั่นบาง ๆ array = array[::-1]ของตัวเองโดยใช้


3
ประโยคสุดท้ายไม่เป็นความจริงนี่ไม่ใช่สิ่งที่ตรงกันข้ามในรายการ; มันควรจะพูดว่าarray[:] = array[::-1]
Antti Haapala


2

ด้วยฟังก์ชั่นในตัวที่น้อยที่สุดสมมติว่าเป็นการตั้งค่าการสัมภาษณ์

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)

1

การแปลความต้องการของคุณเป็น Python โดยตรงที่สุดคือforข้อความนี้:

for i in xrange(len(array) - 1, -1, -1):
   print i, array[i]

นี่ค่อนข้างเป็นความลับ แต่อาจมีประโยชน์



1

คุณสามารถปฏิบัติต่อรายการเช่นเดียวกับสแต็คเพียงโผล่องค์ประกอบออกจากด้านบนสุดของสแต็คจากด้านหลังสุดของรายการ ด้วยวิธีนี้คุณจะได้รับประโยชน์จากคุณสมบัติของสแต็กสุดท้ายก่อน แน่นอนคุณกำลังบริโภคอาร์เรย์ที่ 1 ฉันชอบวิธีนี้เพราะมันเป็นเรื่องง่ายที่คุณจะเห็นรายการหนึ่งถูกใช้ไปจากส่วนหลังขณะที่อีกรายการกำลังถูกสร้างจากส่วนหน้า

>>> l = [1,2,3,4,5,6]; nl=[]
>>> while l:
        nl.append(l.pop())  
>>> print nl
[6, 5, 4, 3, 2, 1]



1

นี่คือวิธีในการประเมินย้อนกลับอย่างเกียจคร้านโดยใช้ตัวสร้าง :

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

1

มี 3 วิธีในการรับรายการที่กลับรายการ:

  1. วิธีการแบ่งส่วน 1: reversed_array = array[-1::-1]

  2. วิธีการแบ่งส่วน 2: reversed_array2 = array[::-1]

  3. ใช้ฟังก์ชั่น builtin: reversed_array = array.reverse()

ฟังก์ชั่นที่สามกลับรายการวัตถุในสถานที่จริง นั่นหมายความว่าจะไม่มีการคัดลอกข้อมูลที่เก่าแก่ นี่เป็นวิธีการที่ดีถ้าคุณไม่ต้องการบำรุงรักษาเวอร์ชั่นเก่า แต่ดูเหมือนจะไม่ใช่วิธีแก้ปัญหาหากคุณต้องการเวอร์ชั่นเก่าและกลับด้าน


0
>>> l = [1, 2, 3, 4, 5]
>>> print(reduce(lambda acc, x: [x] + acc, l, []))
[5, 4, 3, 2, 1]

วิธีนี้จะช้ากว่า 4.5k เท่าl[::-1]และในเวลาเดียวกันก็อ่านออกได้น้อยกว่ามาก ฟังก์ชั่นการเขียนโปรแกรมใน Python ค่อนข้างช้า
Dakkaron
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.