Як отримати останні елементи списку в Python?


Відповіді:


519

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


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.