คุณจะสร้างรายการต่อไปนี้range()
ใน Python ได้อย่างไร?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
คุณจะสร้างรายการต่อไปนี้range()
ใน Python ได้อย่างไร?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
คำตอบ:
ใช้reversed()
ฟังก์ชั่น:
reversed(range(10))
มันมีความหมายมากกว่านี้มาก
ปรับปรุง:
หากคุณต้องการให้เป็นรายการ (ตามที่ btk ชี้ให้เห็น):
list(reversed(range(10)))
ปรับปรุง:
หากคุณต้องการใช้เพียงrange
เพื่อให้ได้ผลลัพธ์เดียวกันคุณสามารถใช้พารามิเตอร์ทั้งหมดได้range(start, stop, step)
ตัวอย่างเช่นในการสร้างรายการ[5,4,3,2,1,0]
คุณสามารถใช้รายการต่อไปนี้:
range(5, -1, -1)
มันอาจจะใช้งานง่ายน้อยลง แต่เป็นความคิดเห็นที่กล่าวถึงนี้มีประสิทธิภาพมากขึ้นและการใช้งานที่ถูกต้องของช่วงสำหรับรายการที่กลับรายการ
range(10)
range(9)
นอกจากนี้ถ้าคุณต้องการให้รายการเต็มรูปแบบ (สำหรับหั่น ฯลฯ ) list(reversed(range(10)))
ที่คุณควรทำ
reversed
ไม่รับเครื่องกำเนิดไฟฟ้าโดยทั่วไป range
แต่ก็ยอมรับ เหตุใดจึงreversed(range(10000))
ต้องจัดสรรหน่วยความจำสำหรับรายการทั้งหมด range
สามารถส่งคืนวัตถุที่ใช้__reversed__
วิธีการที่อนุญาตให้ทำซ้ำย้อนกลับที่มีประสิทธิภาพได้หรือไม่?
ใช้ฟังก์ชันในตัว 'ช่วง' range(start, stop, step)
ลายเซ็นคือ นี้ผลิตลำดับที่ทำให้ตัวเลขเริ่มต้นด้วยstart
และสิ้นสุดถ้าได้รับถึงไม่รวมstop
stop
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
ใน Python 3 สิ่งนี้จะสร้างrange
อ็อบเจกต์ที่ไม่ใช่ลิสต์ซึ่งทำหน้าที่ได้อย่างมีประสิทธิภาพเหมือนกับลิสต์แบบอ่านอย่างเดียว (แต่ใช้หน่วยความจำน้อยกว่าโดยเฉพาะช่วงที่มีขนาดใหญ่)
help(range)
ใน python shell มันจะบอกคุณถึงข้อโต้แย้ง พวกเขาเป็นหมายเลขที่จะเริ่มต้นจำนวนที่จะสิ้นสุด (พิเศษ) และขั้นตอนที่จะดำเนินการดังนั้นจึงเริ่มที่ 9 และลบ 1 จนกว่าจะได้รับถึง -1 (ณ จุดที่มันหยุดโดยไม่กลับมาซึ่งเป็นเหตุผล ช่วงสิ้นสุดที่ 0)
range(start, stop, step)
- เริ่มจากตัวเลขstart
และให้ผลลัพธ์เว้นแต่จะstop
ได้มาถึงเคลื่อนย้ายโดยstep
แต่ละครั้ง
คุณสามารถใช้range(10)[::-1]
ซึ่งเป็นสิ่งเดียวกันrange(9, -1, -1)
และอ่านได้ง่ายขึ้น (ถ้าคุณคุ้นเคยกับsequence[::-1]
สำนวน Python ทั่วไป)
สำหรับผู้ที่สนใจใน "ประสิทธิภาพ" ของตัวเลือกที่รวบรวมจนถึง ...
คำตอบของ Jaime RGPทำให้ฉันรีสตาร์ทคอมพิวเตอร์หลังจากกำหนดเวลาโซลูชันที่ "ท้าทาย" ของJason อย่างแท้จริงตามคำแนะนำของฉัน (ผ่านความคิดเห็น) เพื่อสำรองความอยากรู้อยากเห็นของคุณเกี่ยวกับการหยุดทำงานฉันนำเสนอผลลัพธ์ของฉันที่นี่ (แย่ที่สุด - ก่อน):
คำตอบของ Jason (อาจเป็นเพียงแค่การใช้พลังของความเข้าใจในรายการ ):
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
คำตอบของ martineau (อ่านได้ถ้าคุณคุ้นเคยกับไวยากรณ์ส่วนขยาย ):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
คำตอบของMichałŠrajer (ผู้ที่ได้รับการยอมรับอ่านง่ายมาก):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
คำตอบของ bene (ครั้งแรก แต่ร่างมากในเวลานั้น ):
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
ตัวเลือกสุดท้ายที่ง่ายต่อการจำโดยใช้range(n-1,-1,-1)
สัญกรณ์โดยVal Neekman
for i in range(8, 0, -1)
จะแก้ปัญหานี้ มันจะออก 8 ถึง 1 และ -1 หมายถึงรายการที่กลับรายการ
reverse
เนื่องจากวิธีช่วงสามารถส่งคืนรายการที่กลับรายการได้เมื่อคุณมีการวนซ้ำมากกว่าnรายการและต้องการแทนที่ลำดับของรายการที่ส่งคืนโดยrange(start, stop, step)
คุณต้องใช้พารามิเตอร์ช่วงที่สามซึ่งระบุstep
และตั้งค่าเป็น-1
พารามิเตอร์อื่น ๆ จะถูกปรับตาม:
-1
(มันคุ้มค่าก่อนหน้านี้stop - 1
, stop
เท่ากับ0
)n-1
ขณะที่การใช้พารามิเตอร์เริ่มต้นดังนั้นช่วงที่เทียบเท่า (n) ในลำดับย้อนกลับจะเป็น:
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
readibility กันดูเหมือนว่าจะเร็วกว่าreversed(range(n))
range(n)[::-1]
$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop
เพียงแค่มีคนสงสัยว่า :)
range(1000000000-1,-1,-1)
ด้วย?
timeit range(1000000000-1,-1,-1)
ใช้บรรทัดคำสั่งแทนที่จะดูผลลัพธ์ของฉัน :-)
ข้อกำหนดในคำถามนี้ต้องการlist
จำนวนเต็ม 10 ขนาดตามลำดับจากมากไปน้อย ดังนั้นมาสร้างรายการในไพ ธ อน
# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------
# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>
# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
-1
มันเป็นรูปแบบนี้ที่ทำให้ง่ายต่อการรักษาwrap one's head around this
- วันนี้ฉันเรียนรู้ว่าถ้าต้องมีประสิทธิภาพจริงๆให้ใช้range(n-1, -1, -1)
เมื่อสำรวจช่วงในลำดับที่กลับด้าน
คุณสามารถพิมพ์ตัวเลขย้อนกลับด้วย range () BIF Like,
for number in range ( 10 , 0 , -1 ) :
print ( number )
ผลผลิตจะเป็น [10,9,8,7,6,5,4,3,2,1]
range () - range (start, end, increment / decrement) โดยที่ start รวม, end เป็นเอกสิทธิ์และการเพิ่มขึ้นสามารถเป็นตัวเลขใด ๆ และพฤติกรรมเช่นขั้นตอน
คำถามที่ถามบ่อยมากว่าrange(9, -1, -1)
ดีกว่าreversed(range(10))
ใน Python 3 หรือไม่ ผู้ที่ทำงานในภาษาอื่นด้วยตัววนซ้ำในทันทีมีแนวโน้มที่จะคิดว่าการย้อนกลับ () ต้องแคชค่าทั้งหมดแล้วส่งกลับในลำดับย้อนกลับ สิ่งนี้คือreversed()
ตัวดำเนินการของ Python ไม่ทำงานหากวัตถุเป็นเพียงตัววนซ้ำ วัตถุต้องมีหนึ่งในสองด้านล่างเพื่อให้ reverse () ทำงาน:
len()
และดัชนีจำนวนเต็มผ่าน[]
__reversed__()
วิธีดำเนินการหากคุณพยายามที่จะใช้ reverse () บนวัตถุที่ไม่มีสิ่งใดข้างต้นคุณจะได้รับ:
>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible
ดังนั้นในระยะสั้นไพ ธ อนreversed()
จึงมีความหมายเฉพาะกับอาเรย์เหมือนกับวัตถุดังนั้นมันควรมีประสิทธิภาพเช่นเดียวกับการทำซ้ำไปข้างหน้า
แต่เกี่ยวกับrange()
อะไร นั่นไม่ใช่เครื่องกำเนิดไฟฟ้าใช่ไหม ใน Python 3 เป็นเครื่องกำเนิดไฟฟ้า แต่ถูกห่อในคลาสที่ใช้ทั้งสองอย่าง ดังนั้นrange(100000)
ไม่ใช้หน่วยความจำมาก แต่ก็ยังรองรับการทำดัชนีและย้อนกลับที่มีประสิทธิภาพ
ดังนั้นโดยสรุปคุณสามารถใช้งานได้reversed(range(10))
โดยไม่กระทบต่อประสิทธิภาพ
ฉันเชื่อว่านี่จะช่วยได้
range(5)[::-1]
ด้านล่างคือการใช้งาน:
for i in range(5)[::-1]:
print i
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))
เกิดข้อผิดพลาดน้อยกว่า ไม่มีความผิด Asinox เพียงแค่การสังเกตอย่างซื่อสัตย์
ใช้โดยไม่ต้อง [:: - 1] หรือกลับรายการ -
def reverse(text):
result = []
for index in range(len(text)-1,-1,-1):
c = text[index]
result.append(c)
return ''.join(result)
print reverse("python!")
"python!"[::-1]
?
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
คุณไม่จำเป็นต้องใช้ฟังก์ชันช่วงคุณสามารถทำรายการ [:: - 1] ซึ่งควรส่งคืนรายการในลำดับที่กลับรายการอย่างรวดเร็วโดยไม่ต้องใช้ส่วนเพิ่มเติมใด ๆ
สมมติว่าคุณมีรายการเรียกมันว่า a = {1,2,3,4,5} ตอนนี้ถ้าคุณต้องการพิมพ์รายการในสิ่งที่ตรงกันข้ามจากนั้นใช้รหัสต่อไปนี้
a.reverse
for i in a:
print(i)
ฉันรู้ว่าคุณถามโดยใช้ช่วง แต่มันตอบแล้ว
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
เป็นรูปแบบที่ถูกต้อง ถ้าคุณใช้
reversed(range(10))
คุณจะไม่ได้รับกรณี 0 ตัวอย่างเช่นสมมติว่า 10 ไม่ใช่หมายเลขเวทมนต์และตัวแปรที่คุณใช้ในการค้นหาเริ่มจากย้อนกลับ หากกรณีของคุณเป็น 0 การย้อนกลับ (ช่วง (0)) จะไม่ดำเนินการซึ่งผิดถ้าคุณบังเอิญมีวัตถุหนึ่งชิ้นในดัชนีศูนย์
ฉันคิดว่าหลายคน (ในฐานะตัวเอง) อาจสนใจในกรณีทั่วไปของการสำรวจรายการที่มีอยู่ในลำดับที่กลับรายการแทนตามที่ระบุไว้ในชื่อแทนที่จะสร้างดัชนีสำหรับการสำรวจเส้นทางดังกล่าว
แม้ว่าคำตอบที่ถูกต้องทั้งหมดยังคงสมบูรณ์แบบสำหรับกรณีนี้ฉันต้องการชี้ให้เห็นว่าการเปรียบเทียบประสิทธิภาพที่ทำในคำตอบของ Wolfมีไว้สำหรับสร้างดัชนีเท่านั้น ดังนั้นฉันจึงสร้างมาตรฐานที่คล้ายคลึงกันสำหรับการสำรวจรายการที่มีอยู่ในลำดับที่กลับรายการ
TL; DR a[::-1]
เร็วที่สุด
วิชาบังคับก่อน:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
อย่างที่คุณเห็นในกรณีนี้ไม่จำเป็นต้องสร้างดัชนีอย่างชัดเจนดังนั้นวิธีที่เร็วที่สุดคือวิธีที่ทำให้การดำเนินการพิเศษน้อยลง
หมายเหตุ: ผมทดสอบใน JupyterLab ซึ่งมีประโยชน์คำสั่ง %timeit
"มายากล" มันใช้มาตรฐานtimeit.timeit
ภายใต้ประทุน ผ่านการทดสอบสำหรับ Python 3.7.3