Отримання останнього елемента списку


Відповіді:


3102

some_list[-1] є найкоротшим і найбільш піфонічним.

Насправді ви можете зробити набагато більше з цим синтаксисом. some_list[-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- це буде красивий рядок коду
Дмитро П.

256

Якщо ваш str()або list()об’єкти можуть виявитися порожніми так: astr = ''або alist = [], ви можете використовувати alist[-1:]замість alist[-1]об'єкта "однаковість".

Значення цього полягає в:

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

Де робиться відмінність у тому, що повернення об'єкта з порожнім списком або порожній об'єкт str більше схоже на "останній елемент", ніж об'єкт виключення.


25
Зрозуміло, тому що я вважаю, що ядро ​​цієї відповіді невірно. Отримання списку, коли потрібно, щоб елемент лише відкладав неминучий "індекс списку поза діапазоном" - і саме це повинно статися при спробі отримати елемент із порожнього списку. Для Strings astr [-1:] може бути правильним підходом, оскільки він повертає той самий тип, що і astr [-1], але я не думаю, що ':' допомагає боротися з порожніми списками (і питання стосується списків) . Якщо ідея полягає у використанні "alist [-1:]" як умовному замість "len (alist)> 0", я думаю, що набагато зручніше використовувати пізніше. (радий подати заявку, якщо я щось пропустив)
Stan Kurdziel

9
Ви проголосуєте проти, це зрозуміло і дійсно. Однак я вважаю, що існують два основні табори, для яких об'єкти виключення призначені. Однозначно, винятки зупиняють ваш додаток. Один табір використовує винятки у клавішах спробу, оскільки інший табір використовує структуру if len (alist)> 0:. У будь-якому випадку, виняток становлять об'єкти, які зупиняють ваш код. І як такий мені менш об’єкт послідовності, як потім повертаються "null"-наслідки, які не зупиняють ваш код. Я вважаю за краще використовувати пункти IF для тестування об'єктів "null" замість об'єктів, які зупиняють мій код, який я попереджую клавішею спробувати.
DevPlayer

6
Отриманий через те, що синтаксис зрізів вартий обговорення, проте я погоджуюся з @StanKurdziel, що морфологія неправильна, ви просто переміщаєте стовп цілі - я знайшов своє власне рішення, пов’язане з первинним використанням ", додайте це до списку, якщо ви цього не зробили 't вже додати його' (дельта-лінійні графіки), тому комбінований вираз if len(my_vector) == 0 or my_vector[-1] != update_valє працездатною схемою. але це, звичайно, не глобальне рішення - було б непогано мати форму синтаксису, де результат не був
Марк Маллін

17
xs[-1] if xs else None
Габріель

2
Чому б ви "уникали" IndexError? Якщо ви спробуєте проіндексувати порожній список або рядок, ви отримаєте виняток. Якщо ви хочете впоратися з цим винятком, використовуйте спробу / виняток - ось для чого він потрібен.
Кріс Джонсон

93

Ви також можете зробити:

alist.pop()

Це залежить від того, що ви хочете зробити зі своїм списком, оскільки pop()метод видалить останній елемент.


70

Найпростіший спосіб відображення останнього елемента в python - це

>>> 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 прив'язане до непотрібного новоствореного списку:

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

Якщо ви не збираєтеся нічого робити із цим списком, це буде більше:

*_, last = a_list

Або, дійсно, якщо ви знаєте, що це список (або принаймні приймає нотації підписки):

last = a_list[-1]

У функції

Коментатор сказав:

Я хотів би, щоб у Python була функція для першого () і останнього (), як це робить Лісп ... він позбувся б багатьох непотрібних лямбда-функцій.

Їх було б досить просто визначити:

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
Напевно, погано вважати, що мутація оригінального списку зазвичай не рекомендується, оскільки, зрештою, це дуже часто виконується
Аарон

6

Ви також можете використовувати код нижче, якщо ви не хочете отримати IndexError, коли список порожній.

next(reversed(some_list), None)

4

Гаразд, а як же бути загальним майже у всіх мовних способах items[len(items) - 1]? Це IMO найпростіший спосіб отримати останній елемент, оскільки він не вимагає нічого пітонічного знання.


3
items [len (items) - 1] - це по суті те, що робить Python під кришкою, але оскільки тривалість послідовності вже зберігається в послідовності, її не потрібно рахувати, ви створюєте більше роботи, ніж потрібно.
Ден Гейл

21
оскільки ви пишете Python, ви дійсно повинні намагатися бути більше Pythonic
Майкл Ву

5
@MichaelWu Немає сенсу цього робити. Пітонічний спосіб часто не є зрозумілим, потрібно більше уваги, де вам доведеться запроваджувати нових людей до проекту, і, звичайно, він би не працював, коли вам доведеться переходити на інші мови, такі як Java - ви не можете використовувати специфічні знання Python. Якщо ви пропустите пітонічний шлях, наскільки це можливо, то також повернутися до проекту через місяці / роки набагато простіше.
Радек Анушевський

7
@Pneumokok Ви заперечуєте, але я б заперечував, що індексація списків є дуже базовою технікою Python порівняно з генераторами, що говорять. Крім того, навіщо турбуватися використовувати що-небудь крім C або, можливо, JavaScript, якщо ви не збираєтесь скористатися індивідуальними мовними засобами та синтаксисом? Тоді ви зможете послідовно робити все важко у всіх своїх проектах.
Меттью Пурдон

Хоча це не дуже пітонічно, я думаю, що це в деяких аспектах краще, ніж some_list[-1]підхід, тому що це більш логічно і показує, що насправді робить краще, ніж some_list[-1]на мою думку.
Байрон Філер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.