Відповіді:
Для цього можна використовувати негативні цілі числа з оператором нарізки. Ось приклад використання інтерпретатора CLI 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 [].
Нарізка 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]
isliceisliceз модуля 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 вимагають встановлення сторонньої бібліотеки, яка може бути корисною для деяких користувачів.