Ответы:
Для этого вы можете использовать отрицательные целые числа с оператором нарезки. Вот пример использования интерпретатора 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:]
-0
это 0
. Так что a[-0:]
возвращает целые a
, а не последние нулевые элементы []
. Для защиты нуля вы можете использовать a[-n:] if n > 0 else []
.
Нарезка 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]
Последние 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]
Вот несколько вариантов получения «хвостовых» элементов итерируемого:
Дано
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))
подробности
iter(iterable)
.itertools
рецепт . Он обобщен для работы с любой итерацией и решает проблему итератора в последнем решении. Этот рецепт должен быть реализован вручную, поскольку он официально не включен в itertools
модуль.more_itertools
(установить через > pip install more-itertools
); см more_itertools.tail
.itertools
библиотеки. Обратите внимание, itertools.islice
не поддерживает негативную нарезку . more_itertools
том, что обобщает itertools.islice
для поддержки отрицательного среза; см more_itertools.islice_extended
.Какой из них я использую?
Это зависит . В большинстве случаев срез (вариант A, как упоминалось в других ответах) является наиболее простым вариантом, поскольку он встроен в язык и поддерживает большинство итерируемых типов. Для более общих итераторов используйте любой из оставшихся вариантов. Обратите внимание, что опции C и E требуют установки сторонней библиотеки, которая может оказаться полезной для некоторых пользователей.