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