Получение последнего элемента списка

Ответы:

3110

some_list[-1] самый короткий и самый Pythonic.

На самом деле, вы можете сделать гораздо больше с этим синтаксисом. 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- это была бы красивая строка кода
Дмитрий П.
257

Если ваши 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 является более «последним элементом», чем объект исключения.

DevPlayer
источник
26
Проголосовал, потому что я считаю, что суть этого ответа неверна. Получение списка, когда вы хотите, чтобы элемент только откладывал неизбежный «индекс списка вне диапазона» - и это то, что должно происходить при попытке получить элемент из пустого списка. Для строк astr [-1:] может быть правильным подходом, так как он возвращает тот же тип, что и astr [-1], но я не думаю, что ':' помогает иметь дело с пустыми списками (и вопрос о списках) , Если идея состоит в том, чтобы использовать «alist [-1:]» в качестве условного вместо «len (alist)> 0», я думаю, что будет гораздо удобнее использовать позже. (рад объявить, если я что-то пропустил)
Стэн Курджиль
9
Вы отрицаете голос, это понятно и справедливо. Однако я считаю, что есть два основных лагеря, для которых предназначены объекты исключений. Одна уверенность в том, что исключения останавливают ваше приложение. Один лагерь использует исключения в предложениях try, а другой - вместо структуры len (alist)> 0 :. В любом случае исключения - это объекты, которые останавливают ваш код. И как таковой для меня это менее последовательный объект, чем возвращаемые «нулевые» последовательности, которые не останавливают ваш код. Я предпочитаю использовать предложения IF для проверки «нулевых» объектов, а не объектов, которые останавливают мой код, который я выгружаю предложением try.
DevPlayer
6
Проголосовал, потому что стоит обсудить синтаксис среза, однако я согласен с @StanKurdziel, что морфология неправильная, вы просто перемещаете стойку ворот - я обнаружил, что мое собственное решение было связано с основным использованием «добавьте это в список, если вы не сделали этого». не добавляйте его (дельта-графы), поэтому комбинированное выражение if len(my_vector) == 0 or my_vector[-1] != update_valявляется работоспособным шаблоном. но это, безусловно, не глобальное решение - было бы неплохо иметь синтаксическую форму, в которой результатом был None
Марк Маллин
17
xs[-1] if xs else None
Габриэль
2
Зачем вам «избегать» IndexError? Если вы попытаетесь проиндексировать пустой список или строку, вы получите исключение. Если вы хотите обработать это исключение, используйте попытку / исключение - вот для чего оно.
Крис Джонсон
94

Вы также можете сделать:

alist.pop()

Это зависит от того, что вы хотите сделать со своим списком, потому что pop()метод удалит последний элемент.

Телец Олсон
источник
71

Самый простой способ отобразить последний элемент в Python

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

Есть много других методов для достижения такой цели, но они короткие и приятные в использовании.

Атул Арвинд
источник
2
Если длина вашего списка равна нулю, это решение list[-1]будет работать, пока не произойдет ошибка.
anon01
Какая? Зачем ты a[-1:][0] вообще ? Он обеспечивает в a[-1]любом случае тоже. Пояснения пожалуйста?
Kaboom
52

В 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 была функция для first () и last (), как это делает 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
Аарон Холл
источник
14

Чтобы предотвратить 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'
Валентин Подкаменный
источник
11

Другой метод:

some_list.reverse() 
some_list[0]
Санджай Прадип
источник
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'
pylang
источник
6

list[-1]извлечет последний элемент списка без изменения списка. list.pop()извлечет последний элемент списка, но он будет изменять / изменять исходный список. Как правило, изменение оригинального списка не рекомендуется.

В качестве альтернативы, если по какой-то причине вы ищете что-то менее питоническое, вы можете использовать его list[len(list)-1], предполагая, что список не пуст.

Зондирование нарциссов
источник
2
Вероятно, неправильно предполагать, что изменение оригинального списка обычно не рекомендуется, потому что, в конце концов, это очень часто выполняется
Аарон
6

Вы также можете использовать код ниже, если вы не хотите получать IndexError, когда список пуст.

next(reversed(some_list), None)
Явуз Местер
источник
4

Хорошо, но как насчет общего почти во всех языковых отношениях items[len(items) - 1]? Это ИМО самый простой способ получить последний элемент, потому что он не требует ничего питонического знания.

Радек Анушевский
источник
3
items [len (items) - 1] - это, по сути, то, что Python делает под капотом, но поскольку len последовательности уже хранится в последовательности, нет необходимости считать его, вы создаете больше работы, чем необходимо.
Дэн Гейл
21
так как вы пишете Python, вы действительно должны стараться быть более Pythonic
Майкл Ву
5
@MichaelWu Нет смысла это делать. Pythonic часто не требует пояснений, требует большего внимания, когда вам нужно представить новых людей в проект, и, конечно, не будет работать, когда вам придется переключаться на другие языки, такие как Java - вы не можете использовать специфические знания Python. Когда вы пропускаете питонический путь, насколько это возможно, то возвращаться к проекту через месяцы / годы гораздо проще.
Радек Анушевский
7
@Pneumokok Вы говорите правильно, но я бы сказал, что индексация списков является очень простой техникой Python по сравнению, скажем, с генераторами. Кроме того, зачем использовать что-либо кроме C или, возможно, javascript, если вы не собираетесь использовать преимущества отдельных языковых инструментов и синтаксиса? Тогда вы можете последовательно делать все трудным путем во всех ваших проектах.
Мэтью Пурдон
Хотя это не очень питонично, я думаю, что это в некоторых отношениях лучше, чем some_list[-1]подход, потому что он более логичен и показывает, что он на самом деле делает лучше, чем, some_list[-1]на мой взгляд.
Байрон Филер