รับองค์ประกอบสุดท้ายของรายการ


คำตอบ:


3105

some_list[-1] เป็น Pythonic ที่สั้นที่สุดและมากที่สุด

ที่จริงแล้วคุณสามารถทำอะไรได้มากกว่านี้กับไวยากรณ์นี้ some_list[-n]ไวยากรณ์ได้ element ที่ n ไปสุดท้าย ดังนั้นsome_list[-1]ได้รับองค์ประกอบที่ผ่านมาsome_list[-2]ได้รับสองสุดท้าย ฯลฯ ทุกทางลงไปsome_list[-len(some_list)]ซึ่งจะช่วยให้คุณองค์ประกอบแรก

คุณยังสามารถตั้งค่าองค์ประกอบรายการได้ด้วยวิธีนี้ ตัวอย่างเช่น

>>> some_list = [1, 2, 3]
>>> some_list[-1] = 5 # Set the last element
>>> some_list[-2] = 3 # Set the second to last element
>>> some_list
[1, 3, 5]

โปรดทราบว่าการรับไอเท็มตามดัชนีจะเพิ่มIndexErrorหากไม่มีรายการที่คาดหวัง ซึ่งหมายความว่าsome_list[-1]จะเพิ่มข้อยกเว้นหากsome_listว่างเปล่าเนื่องจากรายการว่างไม่สามารถมีองค์ประกอบสุดท้ายได้


6
ฉันคิดถึงอะไรบางอย่างsome_list.last- มันจะเป็นรหัสที่สวยงาม
Dmitry P.

256

หากวัตถุstr()หรือlist()วัตถุของคุณอาจว่างเปล่าดังนั้น: astr = ''หรือalist = []คุณอาจต้องการใช้alist[-1:]แทนalist[-1]วัตถุ "sameness"

ความสำคัญของสิ่งนี้คือ:

alist = []
alist[-1]   # will generate an IndexError exception whereas 
alist[-1:]  # will return an empty list
astr = ''
astr[-1]    # will generate an IndexError exception whereas
astr[-1:]   # will return an empty str

ในกรณีที่มีการแยกความแตกต่างคือการส่งคืนวัตถุที่ว่างเปล่าหรือวัตถุที่ว่างเปล่าคือ "องค์ประกอบสุดท้าย" - เหมือนเป็นวัตถุยกเว้น


26
ลงเนื่องจากฉันรู้สึกว่าคำตอบหลักนี้ไม่ถูกต้อง การรับรายการเมื่อคุณต้องการให้องค์ประกอบเลื่อนการ "ดัชนีรายการที่อยู่นอกช่วง" ออกไปอย่างหลีกเลี่ยงไม่ได้ - และนั่นคือสิ่งที่จะเกิดขึ้นเมื่อพยายามรับองค์ประกอบจากรายการที่ว่างเปล่า สำหรับ Strings astr [-1:] อาจเป็นวิธีที่ถูกต้องเนื่องจากมันคืนค่าชนิดเดียวกับ astr [-1] แต่ฉันไม่คิดว่า ':' จะช่วยจัดการรายการที่ว่างเปล่า (และคำถามเกี่ยวกับรายการ) . หากแนวคิดคือใช้ "alist [-1:]" เป็นแบบมีเงื่อนไขแทนที่จะเป็น "len (alist)> 0" ฉันคิดว่าสามารถอ่านได้ในภายหลังเพื่อใช้ในภายหลัง (ยินดีที่จะโหวตถ้าฉันพลาดบางอย่าง)
Stan Kurdziel

9
คุณลงคะแนนสามารถเข้าใจและใช้ได้จริง อย่างไรก็ตามฉันพบว่ามีสองค่ายพื้นฐานเกี่ยวกับวัตถุข้อยกเว้นที่มีไว้สำหรับ ความเชื่อมั่นอย่างหนึ่งคือข้อยกเว้นจะหยุดแอปของคุณ ค่ายหนึ่งใช้ข้อยกเว้นในส่วนคำสั่งลองเนื่องจากค่ายอื่นจะใช้ if (alist)> 0: โครงสร้างแทน ในกรณีใด ๆ ข้อยกเว้นคือวัตถุที่หยุดโค้ดของคุณ และเช่นฉันเป็นวัตถุลำดับน้อยเช่นกลับแล้ว "โมฆะ" - ผลที่ไม่หยุดรหัสของคุณ การตั้งค่าของฉันคือการใช้ IF ประโยคเพื่อทดสอบวัตถุ "โมฆะ" แทนวัตถุที่หยุดรหัสของฉันที่ฉัน preempt กับประโยคข้อลอง
DevPlayer

6
อัปโหลดแล้วเนื่องจากไวยากรณ์ของส่วนแบ่งมีค่าสำหรับการสนทนาอย่างไรก็ตามฉันเห็นด้วยกับ @StanKurdziel ว่าสัณฐานวิทยานั้นผิดคุณเพิ่งย้ายเสาประตู - ฉันพบว่าโซลูชันของตัวเองเกี่ยวข้องกับการใช้งานหลักของ 'เพิ่มรายการนี้ถ้าคุณไม่ได้ ยังไม่ได้เพิ่ม (กราฟเส้นเดลต้า) ดังนั้นนิพจน์ที่รวมกันif len(my_vector) == 0 or my_vector[-1] != update_valเป็นรูปแบบที่ใช้การได้ แต่แน่นอนว่าไม่ใช่วิธีแก้ปัญหาระดับโลก - มันจะดีถ้ามีรูปแบบไวยากรณ์ที่ไม่มีผลลัพธ์
Mark Mullin

17
xs[-1] if xs else None
กาเบรียล

2
ทำไมคุณจะ "หลีกเลี่ยง" ดัชนีที่ผิดพลาด? หากคุณพยายามทำดัชนีรายการหรือสตริงว่างคุณจะได้รับข้อยกเว้น หากคุณต้องการจัดการข้อยกเว้นนั้นลองใช้ / ยกเว้น - นั่นคือสิ่งที่มันมีไว้
คริสจอห์นสัน

93

คุณยังสามารถทำสิ่งต่อไปนี้

alist.pop()

ขึ้นอยู่กับสิ่งที่คุณต้องการจะทำกับรายการของคุณเพราะpop()วิธีการจะลบองค์ประกอบสุดท้าย


70

วิธีที่ง่ายที่สุดในการแสดงองค์ประกอบสุดท้ายในหลามคือ

>>> list[-1:] # returns indexed value
    [3]
>>> list[-1]  # returns value
    3

มีวิธีการอื่น ๆ อีกมากมายเพื่อให้บรรลุเป้าหมายดังกล่าว แต่วิธีนี้สั้นและน่าใช้


2
หากความยาวรายการของคุณเป็นศูนย์โซลูชันนี้จะทำงานในขณะที่list[-1]จะเกิดข้อผิดพลาด
anon01

อะไร? ทำไมคุณจะทำอย่างไรa[-1:][0] ที่ทุกคน ? เขาให้a[-1]อะไรต่อไปด้วย กรุณาอธิบาย
kaboom

51

ใน Python คุณจะได้องค์ประกอบสุดท้ายของรายการได้อย่างไร

เพื่อให้ได้องค์ประกอบสุดท้าย

  • โดยไม่ต้องแก้ไขรายการและ
  • สมมติว่าคุณรู้ว่ารายการมีองค์ประกอบสุดท้าย (นั่นคือมันไม่ว่างเปล่า)

ส่ง-1ไปยังสัญกรณ์ห้อย:

>>> a_list = ['zero', 'one', 'two', 'three']
>>> a_list[-1]
'three'

คำอธิบาย

ดัชนีและชิ้นสามารถใช้จำนวนเต็มลบเป็นอาร์กิวเมนต์

ฉันได้แก้ไขตัวอย่างจากเอกสารเพื่อระบุรายการในลำดับแต่ละอ้างอิงดัชนีในกรณีนี้ในสตริง"Python", -1อ้างอิงองค์ประกอบสุดท้าย, ตัวอักษร'n':

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1

>>> p = 'Python'
>>> p[-1]
'n'

การมอบหมายผ่านการเปิดออกซ้ำได้

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

>>> *head, last = a_list
>>> last
'three'

ชื่อตัวแปรส่วนหัวถูกผูกไว้กับรายการที่สร้างขึ้นใหม่โดยไม่จำเป็น:

>>> head
['zero', 'one', 'two']

หากคุณตั้งใจจะไม่ทำอะไรกับรายการนี้จะเป็นเรื่องเพิ่มเติม:

*_, last = a_list

หรือจริงๆถ้าคุณรู้ว่ามันเป็นรายการ (หรืออย่างน้อยก็ยอมรับสัญกรณ์ห้อย):

last = a_list[-1]

ในฟังก์ชั่น

ผู้วิจารณ์พูดว่า:

ฉันหวังว่าหลามจะมีฟังก์ชั่นสำหรับแรก () และสุดท้าย () เหมือน Lisp ทำ ... มันจะกำจัดฟังก์ชั่นแลมบ์ดาที่ไม่จำเป็นออกไปมากมาย

เหล่านี้จะค่อนข้างง่ายในการกำหนด:

def last(a_list):
    return a_list[-1]

def first(a_list):
    return a_list[0]

หรือใช้operator.itemgetter:

>>> import operator
>>> last = operator.itemgetter(-1)
>>> first = operator.itemgetter(0)

ในกรณีใดกรณีหนึ่ง:

>>> last(a_list)
'three'
>>> first(a_list)
'zero'

กรณีพิเศษ

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

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

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

หั่น

ชิ้นส่วนของรายการส่งคืนรายการใหม่ - เพื่อให้เราสามารถแบ่งจาก -1 ถึงท้ายถ้าเราต้องการองค์ประกอบในรายการใหม่:

>>> a_slice = a_list[-1:]
>>> a_slice
['three']

นี่เป็นส่วนของการไม่ล้มเหลวหากรายการว่างเปล่า:

>>> empty_list = []
>>> tail = empty_list[-1:]
>>> if tail:
...     do_something(tail)

ในขณะที่ความพยายามในการเข้าถึงโดยดัชนีจะเพิ่มสิ่งIndexErrorที่ต้องจัดการ:

>>> empty_list[-1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

แต่อีกครั้งการหั่นเพื่อจุดประสงค์นี้ควรจะทำก็ต่อเมื่อคุณต้องการ:

  • สร้างรายการใหม่
  • และรายการใหม่จะว่างเปล่าถ้ารายการก่อนหน้าว่างเปล่า

for ลูป

ในฐานะที่เป็นคุณสมบัติของ Python ไม่มีการกำหนดขอบเขตภายในในการforวนซ้ำ

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

>>> def do_something(arg): pass
>>> for item in a_list:
...     do_something(item)
...     
>>> item
'three'

นี่ไม่ใช่ความหมายสุดท้ายในรายการ นี่คือความหมายสุดท้ายของชื่อที่itemถูกผูกไว้

>>> def do_something(arg): raise Exception
>>> for item in a_list:
...     do_something(item)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 1, in do_something
Exception
>>> item
'zero'

ดังนั้นสิ่งนี้ควรใช้เพื่อรับองค์ประกอบสุดท้ายหากคุณ

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

รับและลบมัน

นอกจากนี้เรายังสามารถกลายพันธุ์รายการเดิมของเราโดยการลบและกลับองค์ประกอบสุดท้าย:

>>> a_list.pop(-1)
'three'
>>> a_list
['zero', 'one', 'two']

แต่ตอนนี้มีการแก้ไขรายการเดิม

( -1จริงๆแล้วเป็นอาร์กิวเมนต์เริ่มต้นดังนั้นlist.popสามารถนำมาใช้โดยไม่มีอาร์กิวเมนต์ดัชนี):

>>> a_list.pop()
'two'

ทำเช่นนี้หาก

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

กรณีเหล่านี้เป็นกรณีการใช้งานที่ถูกต้อง แต่ไม่บ่อยนัก

บันทึกส่วนที่เหลือของการย้อนกลับในภายหลัง:

ฉันไม่รู้ว่าทำไมคุณถึงทำ แต่เพื่อความสมบูรณ์เนื่องจากreversedส่งคืนตัววนซ้ำ (ซึ่งรองรับโปรโตคอลตัววนซ้ำ) คุณสามารถส่งผลลัพธ์ไปที่next:

>>> next(reversed([1,2,3]))
3

ดังนั้นจึงเหมือนกับการย้อนกลับของสิ่งนี้:

>>> next(iter([1,2,3]))
1

แต่ฉันไม่สามารถคิดได้ว่ามีเหตุผลที่ดีที่จะทำสิ่งนี้เว้นแต่ว่าคุณจะต้องมีตัววนซ้ำย้อนกลับที่เหลือในภายหลังซึ่งอาจมีลักษณะเช่นนี้:

reverse_iterator = reversed([1,2,3])
last_element = next(reverse_iterator)

use_later = list(reverse_iterator)

และตอนนี้:

>>> use_later
[2, 1]
>>> last_element
3

13

เพื่อป้องกันIndexError: list index out of rangeใช้ไวยากรณ์นี้:

mylist = [1, 2, 3, 4]

# With None as default value:
value = mylist and mylist[-1]

# With specified default value (option 1):
value = mylist and mylist[-1] or 'default'

# With specified default value (option 2):
value = mylist[-1] if mylist else 'default'


10

lst[-1]เป็นวิธีที่ดีที่สุด แต่ด้วยความสามารถทั่วไปที่พิจารณาได้more_itertools.last:

รหัส

import more_itertools as mit


mit.last([0, 1, 2, 3])
# 3

mit.last(iter([1, 2, 3]))
# 3

mit.last([], "some default")
# 'some default'

6

list[-1]จะดึงองค์ประกอบสุดท้ายของรายการโดยไม่เปลี่ยนรายการ list.pop()จะดึงองค์ประกอบสุดท้ายของรายการ แต่มันจะกลายพันธุ์ / เปลี่ยนรายการเดิม โดยปกติแล้วไม่แนะนำให้ทำการผ่าเหล่ารายการดั้งเดิม

อีกวิธีหนึ่งถ้าด้วยเหตุผลบางอย่างคุณกำลังมองหาบางสิ่งบางอย่างที่ไพเราะน้อยกว่าคุณสามารถใช้list[len(list)-1]โดยสมมติว่ารายการไม่ว่างเปล่า


2
มันอาจจะไม่ดีที่จะสันนิษฐานว่าการกลายพันธุ์รายการเดิมนั้นมักจะไม่แนะนำเพราะหลังจากนั้นจะมีการดำเนินการทั่วไปมาก
Aaron

6

นอกจากนี้คุณยังสามารถใช้รหัสด้านล่างหากคุณไม่ต้องการรับ IndexError เมื่อรายการว่างเปล่า

next(reversed(some_list), None)

4

โอเค แต่เรื่องทั่วไปในเกือบทุกภาษาitems[len(items) - 1]คืออะไร? นี่คือ IMO วิธีที่ง่ายที่สุดในการรับองค์ประกอบสุดท้ายเนื่องจากไม่ต้องการความรู้แบบpythonic


3
items [len (items) - 1] เป็นสิ่งที่ Python กำลังทำอยู่ภายใต้ประทุน แต่เนื่องจาก len ของลำดับนั้นถูกเก็บไว้ในลำดับจึงไม่จำเป็นต้องนับมันคุณจึงสร้างงานมากกว่าที่จำเป็น
Dan Gayle

21
เนื่องจากคุณเขียน Python คุณควรพยายามเป็น Pythonic มากกว่านี้
Michael Wu

5
@MichaelWu ไม่มีเหตุผลที่จะทำเช่นนั้น วิธีไพทอนไม่สามารถอธิบายได้ด้วยตนเองต้องการความสนใจมากขึ้นในที่ที่คุณต้องแนะนำคนใหม่ให้กับโครงการและแน่นอนว่าจะไม่ทำงานเมื่อคุณต้องเปลี่ยนไปใช้ภาษาอื่นเช่นจาวา - คุณไม่สามารถใช้ความรู้เฉพาะของ Python เมื่อคุณไม่ใช้วิธีการแบบ pythonic เท่าที่จะเป็นไปได้การกลับไปที่โครงการหลังจากเดือน / ปีนั้นง่ายกว่ามาก
Radek Anuszewski

7
@Pneumokok คุณทำประเด็น แต่ฉันจะยืนยันว่าการจัดทำดัชนีรายการเป็นเทคนิค Python ขั้นพื้นฐานมากเมื่อเทียบกับเครื่องกำเนิดไฟฟ้าพูด นอกจากนี้ทำไมต้องใช้สิ่งอื่นนอกเหนือจาก C หรืออาจจะเป็นจาวาสคริปต์หากคุณไม่ต้องการใช้ประโยชน์จากเครื่องมือและไวยากรณ์แต่ละภาษา จากนั้นคุณสามารถทำทุกสิ่งได้อย่างต่อเนื่องอย่างหนักในทุกโครงการของคุณ
Matthew Purdon

แม้ว่ามันจะไม่ได้เป็น pythonic มาก แต่ฉันคิดว่านี่เป็นบางสิ่งที่ดีกว่าsome_list[-1]วิธีการเพราะมันมีเหตุผลมากกว่าและแสดงให้เห็นว่ามันทำงานได้ดีกว่าsome_list[-1]ในความคิดของฉัน
Byron Filer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.