Мне нужны последние 9 номеров списка, и я уверен, что есть способ сделать это с помощью нарезки, но я не могу его понять. Я могу получить первые 9 вот так:
num_list[0:9]
Мне нужны последние 9 номеров списка, и я уверен, что есть способ сделать это с помощью нарезки, но я не могу его понять. Я могу получить первые 9 вот так:
num_list[0:9]
Для этого вы можете использовать отрицательные целые числа с оператором среза. Вот пример использования интерпретатора командной строки python:
>>> 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 []
.
- person nekketsuuu; 19.07.2018
отрицательный индекс будет отсчитываться с конца списка, поэтому:
num_list[-9:]
Нарезка 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__
специальный метод - который есть в списке , - поэтому вы должны сначала передать свой список (или итерацию с __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
recipe. Он обобщен для работы с любой итерацией и решает проблему итератора в последнем решении. Этот рецепт необходимо реализовать вручную, поскольку он официально не включен в модуль itertools
.more_itertools
(устанавливается через > pip install more-itertools
); см. more_itertools.tail
.itertools
. Обратите внимание: itertools.islice
не поддерживает отрицательное срезы.more_itertools
, который обобщает itertools.islice
для поддержки отрицательного среза; см. more_itertools.islice_extended
.Какой из них использовать?
Это зависит. В большинстве случаев нарезка (вариант A, как упоминалось в других ответах) является наиболее простым вариантом, поскольку он встроен в язык и поддерживает большинство повторяемых типов. Для более общих итераторов используйте любую из оставшихся опций. Обратите внимание, что варианты C и E требуют установки сторонней библиотеки, что может оказаться полезным для некоторых пользователей.