Как получить последние элементы списка в Python?


288

Мне нужны последние 9 чисел в списке, и я уверен, что есть способ сделать это с помощью нарезки, но я не могу этого понять. Я могу получить первые 9, как это:

num_list[0:9]

Ответы:


519

Для этого вы можете использовать отрицательные целые числа с оператором нарезки. Вот пример использования интерпретатора Python CLI:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a[-9:]
[4, 5, 6, 7, 8, 9, 10, 11, 12]

важная черта a[-9:]


11
Обратите внимание, что -0это 0. Так что a[-0:]возвращает целые a, а не последние нулевые элементы []. Для защиты нуля вы можете использовать a[-n:] if n > 0 else [].
nekketsuuu

93

отрицательный индекс будет отсчитываться с конца списка, поэтому:

num_list[-9:]

53

нарезка

Нарезка Python - это невероятно быстрая операция, и это удобный способ быстрого доступа к частям ваших данных.

Запись среза, чтобы получить последние девять элементов из списка (или любой другой последовательности, которая поддерживает его, например, строку), будет выглядеть следующим образом:

num_list[-9:]

Когда я вижу это, я читаю часть в скобках как «9-е от конца до конца». (На самом деле, я мысленно сокращаю это как «-9, на»)

Объяснение:

Полная запись

sequence[start:stop:step]

Но двоеточие - это то, что говорит Python, что вы даете ему фрагмент, а не обычный индекс. Вот почему идиоматический способ копирования списков в Python 2

list_copy = sequence[:]

И очистка их с:

del my_list[:]

(Списки попадают list.copyи list.clearв Python 3.)

Дайте своим кусочкам описательное имя!

Может оказаться полезным отделить формирование среза от передачи его list.__getitem__методу (это то, что делают квадратные скобки ). Даже если вы не новичок в этом, он делает ваш код более читабельным, так что другие, которым, возможно, придется читать ваш код, могут более легко понять, что вы делаете.

Однако вы не можете просто присвоить переменной целые числа, разделенные двоеточиями. Вам нужно использовать объект среза:

last_nine_slice = slice(-9, None)

Второй аргумент, Noneявляется обязательным, так что первый аргумент интерпретируется как startаргумент, иначе это будет stopаргумент .

Затем вы можете передать объект слайса в вашу последовательность:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

islice

isliceиз модуля itertools это еще один эффективный способ получить это. isliceне принимает отрицательные аргументы, так что в идеале ваш итерацию имеет __reversed__специальный метод - список которых действительно есть - так что вы должны сначала передать список (или Iterable с __reversed__) до reversed.

>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>

islice допускает ленивую оценку конвейера данных, поэтому для материализации данных передайте их конструктору (например list):

>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]

Ваше умственное сокращение очень полезно
Swanky Coder

40

Последние 9 элементов можно прочитать слева направо, используя numlist [-9:], или справа налево, используя numlist [: - 10: -1], как вы хотите.

>>> a=range(17)
>>> print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[-9:]
[8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[:-10:-1]
[16, 15, 14, 13, 12, 11, 10, 9, 8]

6

Вот несколько вариантов получения «хвостовых» элементов итерируемого:

Дано

n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Желаемый вывод

[2, 3, 4, 5, 6, 7, 8, 9, 10]

Код

Мы получаем последний вывод, используя любую из следующих опций:

from collections import deque
import itertools

import more_itertools


# A: Slicing
iterable[-n:]


# B: Implement an itertools recipe
def tail(n, iterable):
    """Return an iterator over the last *n* items of *iterable*.

        >>> t = tail(3, 'ABCDEFG')
        >>> list(t)
        ['E', 'F', 'G']

    """
    return iter(deque(iterable, maxlen=n))
list(tail(n, iterable))


# C: Use an implemented recipe, via more_itertools
list(more_itertools.tail(n, iterable))


# D: islice, via itertools
list(itertools.islice(iterable, len(iterable)-n, None))


# E: Negative islice, via more_itertools
list(more_itertools.islice_extended(iterable, -n, None))

подробности

  • A. Традиционная нарезка Python присуща языку. Эта опция работает с последовательностями, такими как строки, списки и кортежи. Однако этот вид нарезки не работает на итераторах , например iter(iterable).
  • Б. itertoolsрецепт . Он обобщен для работы с любой итерацией и решает проблему итератора в последнем решении. Этот рецепт должен быть реализован вручную, поскольку он официально не включен в itertoolsмодуль.
  • C. Многие рецепты, включая последний инструмент (B), были удобно реализованы в сторонних пакетах. Установка и импорт этих этих библиотек исключает ручную реализацию. Одна из этих библиотек называется more_itertools(установить через > pip install more-itertools); см more_itertools.tail.
  • D. Член itertoolsбиблиотеки. Обратите внимание, itertools.islice не поддерживает негативную нарезку .
  • E. Еще один инструмент реализован в more_itertoolsтом, что обобщает itertools.isliceдля поддержки отрицательного среза; см more_itertools.islice_extended.

Какой из них я использую?

Это зависит . В большинстве случаев срез (вариант A, как упоминалось в других ответах) является наиболее простым вариантом, поскольку он встроен в язык и поддерживает большинство итерируемых типов. Для более общих итераторов используйте любой из оставшихся вариантов. Обратите внимание, что опции C и E требуют установки сторонней библиотеки, которая может оказаться полезной для некоторых пользователей.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.