Lấy phần tử cuối cùng của danh sách


2067

Trong Python, làm thế nào để bạn có được phần tử cuối cùng của danh sách?

Câu trả lời:


3108

some_list[-1] là ngắn nhất và Pythonic nhất.

Trong thực tế, bạn có thể làm nhiều hơn với cú pháp này. Các some_list[-n]cú pháp được các yếu tố thứ n-to-ngoái. Vì vậy, some_list[-1]có được phần tử cuối cùng, some_list[-2]phần thứ hai đến cuối cùng, v.v., tất cả các cách xuống some_list[-len(some_list)], cung cấp cho bạn phần tử đầu tiên.

Bạn cũng có thể thiết lập danh sách các yếu tố theo cách này. Ví dụ:

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

Lưu ý rằng việc nhận một mục danh sách theo chỉ mục sẽ tăng IndexErrornếu mục dự kiến ​​không tồn tại. Điều này có nghĩa là some_list[-1]sẽ đưa ra một ngoại lệ nếu some_listtrống, bởi vì một danh sách trống không thể có phần tử cuối cùng.


6
Tôi nhớ một cái gì đó như some_list.last- nó sẽ là dòng mã đẹp
Dmitry P.

257

Nếu cuối cùng str()hoặc list()các đối tượng của bạn có thể trống rỗng như vậy: astr = ''hoặc alist = [], thì bạn có thể muốn sử dụng alist[-1:]thay vì alist[-1]cho đối tượng "giống nhau".

Ý nghĩa của việc này là:

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

Trong đó sự khác biệt đang được thực hiện là việc trả về một đối tượng danh sách trống hoặc đối tượng str trống là "phần tử cuối cùng" giống như một đối tượng ngoại lệ.


26
Bị từ chối vì tôi cảm thấy cốt lõi của câu trả lời này là không chính xác. Lấy danh sách khi bạn muốn một phần tử chỉ hoãn lại "chỉ mục danh sách ngoài phạm vi" không thể tránh khỏi - và đó là điều sẽ xảy ra khi cố gắng lấy một phần tử từ danh sách trống. Đối với String Astr [-1:] có thể là một cách tiếp cận hợp lệ vì nó trả về cùng loại với Astr [-1], nhưng tôi không nghĩ rằng ':' giúp xử lý các danh sách trống (và câu hỏi là về danh sách) . Nếu ý tưởng là sử dụng "alist [-1:]" như một điều kiện thay vì "len (alist)> 0", tôi nghĩ rằng việc sử dụng sau này sẽ dễ đọc hơn nhiều. (vui mừng nâng cấp nếu tôi bỏ lỡ điều gì đó)
Stan Kurdziel

9
Bạn bỏ phiếu là điều dễ hiểu và hợp lệ. Tuy nhiên tôi thấy có hai trại cơ bản về những đối tượng ngoại lệ được dự định cho. Một điều chắc chắn là ngoại lệ dừng ứng dụng của bạn. Một trại sử dụng các ngoại lệ trong các mệnh đề thử vì các trại khác sẽ sử dụng cấu trúc if (alist)> 0: thay thế. Trong mọi trường hợp, ngoại lệ là các đối tượng ngăn chặn mã của bạn. Và như vậy với tôi là các đối tượng chuỗi ít hơn như sau đó trả về "null" - các kết quả không làm dừng mã của bạn. Sở thích của tôi là sử dụng các mệnh đề IF để kiểm tra các đối tượng "null" thay vì các đối tượng tạm dừng mã của tôi mà tôi ưu tiên sử dụng mệnh đề thử.
DevPlayer

6
Được nâng cấp vì cú pháp lát cắt đáng để thảo luận, tuy nhiên tôi đồng ý với @StanKurdziel rằng hình thái sai, bạn chỉ di chuyển cột mục tiêu - Tôi thấy giải pháp của riêng tôi có liên quan đến việc sử dụng chính 'thêm điều này vào danh sách nếu bạn không 'đã thêm nó' (biểu đồ đường delta), vì vậy biểu thức kết hợp if len(my_vector) == 0 or my_vector[-1] != update_vallà một mẫu khả thi. nhưng nó chắc chắn không phải là một giải pháp toàn cầu - thật tuyệt khi có một hình thức cú pháp trong đó Không có kết quả
Mark Mullin

17
xs[-1] if xs else None
Gabriel

2
Tại sao bạn lại "tránh" một IndexError? Nếu bạn cố gắng lập chỉ mục một danh sách hoặc chuỗi trống, bạn sẽ có một ngoại lệ. Nếu bạn muốn xử lý ngoại lệ đó, hãy sử dụng thử / ngoại trừ - đó là những gì nó có.
Chris Johnson

94

Bạn cũng có thể làm:

alist.pop()

Nó phụ thuộc vào những gì bạn muốn làm với danh sách của bạn vì pop()phương thức sẽ xóa phần tử cuối cùng.


71

Cách đơn giản nhất để hiển thị phần tử cuối cùng trong python là

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

có nhiều phương pháp khác để đạt được mục tiêu như vậy nhưng chúng rất ngắn gọn và dễ sử dụng.


2
nếu độ dài danh sách của bạn bằng 0, giải pháp này list[-1]sẽ hoạt động trong khi sẽ xảy ra lỗi.
anon01

Gì? Tại sao bạn sẽ làm gì a[-1:][0] cả ? Dù sao anh cũng cung cấp a[-1]. Xin giải thích?
kaboom

52

Trong Python, làm thế nào để bạn có được phần tử cuối cùng của danh sách?

Để có được yếu tố cuối cùng,

  • mà không sửa đổi danh sách, và
  • giả sử bạn biết danh sách này có phần tử cuối cùng (nghĩa là nó không trống)

chuyển -1đến ký hiệu đăng ký:

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

Giải trình

Các chỉ mục và lát có thể lấy số nguyên âm làm đối số.

Tôi đã sửa đổi một ví dụ từ tài liệu để chỉ ra mục nào trong chuỗi mỗi tham chiếu chỉ mục, trong trường hợp này, trong chuỗi "Python", -1tham chiếu phần tử cuối cùng, ký tự , 'n':

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

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

Chuyển nhượng thông qua giải nén lặp

Phương pháp này có thể cụ thể hóa một danh sách thứ hai một cách không cần thiết cho mục đích chỉ lấy phần tử cuối cùng, nhưng vì mục đích hoàn chỉnh (và vì nó hỗ trợ bất kỳ danh sách lặp nào - không chỉ danh sách):

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

Tên biến, head bị ràng buộc với danh sách mới được tạo không cần thiết:

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

Nếu bạn có ý định không làm gì với danh sách đó, đây sẽ là apropos nhiều hơn:

*_, last = a_list

Hoặc, thực sự, nếu bạn biết đó là một danh sách (hoặc ít nhất là chấp nhận ký hiệu đăng ký):

last = a_list[-1]

Trong một chức năng

Một bình luận cho biết:

Tôi ước Python có một hàm cho First () và last () giống như Lisp ... nó sẽ loại bỏ rất nhiều hàm lambda không cần thiết.

Đây sẽ là khá đơn giản để xác định:

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

def first(a_list):
    return a_list[0]

Hoặc sử dụng operator.itemgetter:

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

Trong cả hai trường hợp:

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

Trường hợp đặc biệt

Nếu bạn đang làm một cái gì đó phức tạp hơn, bạn có thể thấy nó hiệu quả hơn để có được yếu tố cuối cùng theo những cách hơi khác nhau.

Nếu bạn chưa quen với lập trình, bạn nên tránh phần này, bởi vì nó kết hợp các phần khác nhau về mặt ngữ nghĩa với nhau. Nếu bạn thay đổi thuật toán của mình ở một nơi, nó có thể có tác động ngoài ý muốn đối với một dòng mã khác.

Tôi cố gắng cung cấp sự cẩn thận và điều kiện hoàn toàn nhất có thể, nhưng tôi có thể đã bỏ lỡ điều gì đó. Hãy bình luận nếu bạn nghĩ rằng tôi đang để lại một lời cảnh báo.

Cắt lát

Một lát danh sách trả về một danh sách mới - vì vậy chúng ta có thể cắt từ -1 đến cuối nếu chúng ta muốn phần tử trong danh sách mới:

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

Điều này có mặt trái của việc không thất bại nếu danh sách trống:

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

Trong khi cố gắng truy cập bằng chỉ mục sẽ tăng một IndexErroryêu cầu cần được xử lý:

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

Nhưng một lần nữa, cắt lát cho mục đích này chỉ nên được thực hiện nếu bạn cần:

  • một danh sách mới được tạo
  • và danh sách mới để trống nếu danh sách trước trống.

for vòng lặp

Là một tính năng của Python, không có phạm vi bên trong trong một forvòng lặp.

Nếu bạn đang thực hiện một lần lặp hoàn chỉnh trên danh sách, phần tử cuối cùng sẽ vẫn được tham chiếu bởi tên biến được gán trong vòng lặp:

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

Đây không phải là điều cuối cùng trong danh sách. Đây là điều cuối cùng mà cái tên item, bị ràng buộc.

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

Do đó, điều này chỉ nên được sử dụng để có được phần tử cuối cùng nếu bạn

  • đã được lặp, và
  • bạn biết vòng lặp sẽ kết thúc (không bị hỏng hoặc thoát do lỗi), nếu không, nó sẽ trỏ đến phần tử cuối cùng được tham chiếu bởi vòng lặp.

Bắt và loại bỏ nó

Chúng tôi cũng có thể thay đổi danh sách ban đầu của mình bằng cách xóa và trả về phần tử cuối cùng:

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

Nhưng bây giờ danh sách ban đầu được sửa đổi.

( -1thực sự là đối số mặc định, vì vậy list.popcó thể được sử dụng mà không cần đối số chỉ mục):

>>> a_list.pop()
'two'

Chỉ làm điều này nếu

  • bạn biết danh sách có các thành phần trong đó hoặc được chuẩn bị để xử lý ngoại lệ nếu nó trống và
  • bạn có ý định loại bỏ phần tử cuối cùng khỏi danh sách, coi nó như một ngăn xếp.

Đây là những trường hợp sử dụng hợp lệ, nhưng không phổ biến lắm.

Tiết kiệm phần còn lại của ngược lại cho sau này:

Tôi không biết lý do tại sao bạn làm điều đó, nhưng để hoàn thiện, vì reversedtrả về một trình vòng lặp (hỗ trợ giao thức lặp), bạn có thể chuyển kết quả của nó tới next:

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

Vì vậy, nó giống như làm ngược lại điều này:

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

Nhưng tôi không thể nghĩ ra một lý do chính đáng để làm điều này, trừ khi bạn sẽ cần phần còn lại của trình lặp ngược sau, có lẽ sẽ trông giống như thế này:

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

use_later = list(reverse_iterator)

và bây giờ:

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

14

Để ngăn chặn IndexError: list index out of range, sử dụng cú pháp này:

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] là cách tiếp cận tốt nhất, nhưng với các lần lặp chung, hãy xem xét 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]sẽ lấy phần tử cuối cùng của danh sách mà không thay đổi danh sách. list.pop()sẽ lấy phần tử cuối cùng của danh sách, nhưng nó sẽ biến đổi / thay đổi danh sách ban đầu. Thông thường, việc thay đổi danh sách ban đầu không được khuyến khích.

Ngoài ra, nếu, vì một số lý do, bạn đang tìm kiếm thứ gì đó ít pythonic hơn, bạn có thể sử dụng list[len(list)-1], giả sử danh sách không trống.


2
Có lẽ thật tệ khi cho rằng việc thay đổi danh sách ban đầu thường không được khuyến nghị, bởi vì, sau tất cả, nó thường được thực hiện
Aaron

6

Bạn cũng có thể sử dụng mã bên dưới, nếu bạn không muốn nhận IndexError khi danh sách trống.

next(reversed(some_list), None)

4

Ok, nhưng những gì về phổ biến trong hầu hết mọi cách ngôn ngữ items[len(items) - 1]? Đây là IMO cách dễ nhất để có được yếu tố cuối cùng, bởi vì nó không đòi hỏi bất kỳ kiến thức pythonic nào .


3
các mặt hàng [len (vật phẩm) - 1] về cơ bản là những gì Python đang thực hiện, nhưng vì len của một chuỗi đã được lưu trữ trong chuỗi nên không cần phải đếm nó, nên bạn đang tạo ra nhiều công việc hơn mức cần thiết.
Dan Gayle

21
Vì bạn đang viết Python, bạn thực sự nên cố gắng trở thành Pythonic hơn
Michael Wu

5
@MichaelWu Không có ý nghĩa để làm điều đó. Cách Pythonic thường không tự giải thích, cần chú ý nhiều hơn khi bạn phải giới thiệu người mới đến dự án và tất nhiên, sẽ không hiệu quả khi bạn phải chuyển sang các ngôn ngữ khác như Java - bạn không thể sử dụng kiến ​​thức cụ thể của Python. Khi bạn bỏ qua cách pythonic càng tốt, thì việc quay lại dự án sau nhiều tháng / năm sẽ dễ dàng hơn nhiều.
Radek Anuszewski

7
@Pneumokok Bạn đưa ra quan điểm, nhưng tôi sẽ lập luận rằng lập chỉ mục danh sách là một kỹ thuật Python rất cơ bản so với các trình tạo. Ngoài ra, tại sao phải sử dụng bất cứ thứ gì khác ngoài C hoặc có thể là javascript nếu bạn không tận dụng các công cụ và cú pháp ngôn ngữ riêng lẻ? Sau đó, bạn có thể liên tục làm mọi thứ một cách khó khăn trong tất cả các dự án của bạn.
Matthew Purdon

Mặc dù nó không phải là pythonic nhưng tôi nghĩ rằng điều này ở một số khía cạnh tốt hơn so với some_list[-1]cách tiếp cận bởi vì nó hợp lý hơn, và cho thấy những gì nó thực sự đang làm tốt hơn some_list[-1]theo ý kiến ​​của tôi.
Byron Filer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.