Bagaimana cara mendapatkan item terakhir dari daftar di Python?

288

Saya memerlukan 9 angka terakhir dari daftar dan saya yakin ada cara untuk melakukannya dengan mengiris, tetapi saya sepertinya tidak bisa mendapatkannya. Saya bisa mendapatkan 9 yang pertama seperti ini:

num_list[0:9]
Nggak
sumber

Jawaban:

519

Anda dapat menggunakan bilangan bulat negatif dengan operator slicing untuk itu. Berikut ini contoh menggunakan interpreter 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]

garis yang penting adalah a[-9:]

winmith
sumber
11
Perhatikan bahwa -0adalah 0. Jadi a[-0:]mengembalikan keseluruhan a, bukan elemen nol terakhir []. Untuk menjaga nol, Anda dapat menggunakan a[-n:] if n > 0 else [].
nekketsuuu
93

indeks negatif akan dihitung dari akhir daftar, jadi:

num_list[-9:]
cobbal
sumber
53

Mengiris

Mengiris Python adalah operasi yang sangat cepat, dan ini cara mudah untuk mengakses bagian data Anda dengan cepat.

Notasi irisan untuk mendapatkan sembilan elemen terakhir dari daftar (atau urutan lainnya yang mendukungnya, seperti string) akan terlihat seperti ini:

num_list[-9:]

Ketika saya melihat ini, saya membaca bagian dalam tanda kurung sebagai "kesembilan dari akhir, sampai akhir." (Sebenarnya, saya menyingkatnya secara mental sebagai "-9, pada")

Penjelasan:

Notasi lengkapnya adalah

sequence[start:stop:step]

Tapi titik dua adalah apa yang memberi tahu Python bahwa Anda memberinya sepotong dan bukan indeks biasa. Itu sebabnya cara idiomatis menyalin daftar di Python 2 adalah

list_copy = sequence[:]

Dan membersihkannya adalah dengan:

del my_list[:]

(Daftar dapatkan list.copydan list.cleardalam Python 3.)

Berikan iris Anda nama deskriptif!

Anda mungkin merasa berguna untuk memisahkan pembentukan irisan dari meneruskannya ke list.__getitem__metode ( itulah yang dilakukan kurung kotak ). Sekalipun Anda bukan orang baru di sana, itu membuat kode Anda lebih mudah dibaca sehingga orang lain yang mungkin harus membaca kode Anda dapat lebih mudah memahami apa yang Anda lakukan.

Namun, Anda tidak bisa hanya menetapkan beberapa bilangan bulat yang dipisahkan oleh titik dua ke sebuah variabel. Anda perlu menggunakan objek slice:

last_nine_slice = slice(-9, None)

Argumen kedua,, Nonediperlukan, sehingga argumen pertama ditafsirkan sebagai startargumen jika tidak maka akan menjadi stopargumen .

Anda kemudian dapat meneruskan objek irisan ke urutan Anda:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

islice

islicedari modul itertools adalah cara lain yang mungkin dilakukan untuk mendapatkan ini. islicetidak mengambil argumen negatif, jadi idealnya Anda iterable memiliki __reversed__metode khusus - yang daftar tidak memiliki - sehingga Anda harus terlebih dahulu lulus daftar Anda (atau iterable dengan __reversed__) untuk reversed.

>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>

islice memungkinkan evaluasi malas terhadap pipa data, jadi untuk mematerialisasikan data, berikan ke konstruktor (seperti list):

>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]
Aaron Hall
sumber
Singkatan mental Anda sangat membantu
Swanky Coder
40

9 elemen terakhir dapat dibaca dari kiri ke kanan menggunakan numlist [-9:], atau dari kanan ke kiri menggunakan numlist [: - 10: -1], seperti yang Anda inginkan.

>>> 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]
Nikwin
sumber
6

Berikut adalah beberapa opsi untuk mendapatkan item "tail" dari iterable:

Diberikan

n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Output yang Diinginkan

[2, 3, 4, 5, 6, 7, 8, 9, 10]

Kode

Kami mendapatkan output yang terakhir menggunakan salah satu dari opsi berikut:

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))

Detail

  • A. Tradisional Python mengiris melekat bahasa. Opsi ini berfungsi dengan urutan seperti string, daftar, dan tupel. Namun, pengirisan semacam ini tidak berhasil pada iterator , misalnya iter(iterable).
  • B. Sebuah itertoolsresep . Itu digeneralisasi untuk bekerja pada setiap iterable dan menyelesaikan masalah iterator dalam solusi terakhir. Resep ini harus diimplementasikan secara manual karena tidak secara resmi termasuk dalamitertools modul.
  • C. Banyak resep, termasuk alat yang terakhir (B), telah mudah diimplementasikan dalam paket pihak ketiga. Menginstal dan mengimpor perpustakaan ini meniadakan implementasi manual. Salah satu perpustakaan ini disebut more_itertools(install via > pip install more-itertools); lihat more_itertools.tail.
  • D. Seorang anggota itertoolsperpustakaan. Catatan, itertools.islice tidak mendukung irisan negatif .
  • E. Alat lain diimplementasikan dalam more_itertoolsgeneralisasi itertools.isliceuntuk mendukung irisan negatif; lihat more_itertools.islice_extended.

Yang mana yang saya gunakan?

Itu tergantung . Dalam kebanyakan kasus, mengiris (opsi A, seperti yang disebutkan dalam jawaban lain) adalah opsi yang paling sederhana karena mengiris bahasa dan mendukung tipe yang paling dapat diubah. Untuk iterator yang lebih umum, gunakan salah satu opsi yang tersisa. Catatan, opsi C dan E perlu menginstal perpustakaan pihak ketiga, yang mungkin berguna bagi sebagian pengguna.

pylang
sumber