Làm thế nào để có được các mục cuối cùng của danh sách trong Python?


Câu trả lời:


519

Bạn có thể sử dụng số nguyên âm với toán tử cắt cho điều đó. Đây là một ví dụ sử dụng trình thông dịch 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]

dòng quan trọng là a[-9:]


11
Lưu ý đó -00. Vì vậy, a[-0:]trả về toàn bộ a, không phải là các yếu tố không cuối cùng []. Để bảo vệ số không, bạn có thể sử dụng a[-n:] if n > 0 else [].
nekketsuuu

93

một chỉ số tiêu cực sẽ được tính từ cuối danh sách, vì vậy:

num_list[-9:]

53

Cắt lát

Python cắt lát là một hoạt động cực kỳ nhanh chóng và đó là một cách thuận tiện để truy cập nhanh các phần dữ liệu của bạn.

Ký hiệu lát để lấy chín phần tử cuối cùng từ một danh sách (hoặc bất kỳ chuỗi nào khác hỗ trợ nó, giống như một chuỗi) sẽ trông như thế này:

num_list[-9:]

Khi tôi thấy điều này, tôi đọc phần trong ngoặc là "thứ 9 từ cuối đến cuối". (Trên thực tế, tôi viết tắt nó là "-9, on")

Giải trình:

Ký hiệu đầy đủ là

sequence[start:stop:step]

Nhưng dấu hai chấm là thứ cho Python biết bạn đang cho nó một lát và không phải là một chỉ mục thông thường. Đó là lý do tại sao cách thức sao chép danh sách trong Python 2 là

list_copy = sequence[:]

Và xóa chúng là với:

del my_list[:]

(Danh sách nhận list.copylist.cleartrong Python 3.)

Đặt cho lát của bạn một cái tên mô tả!

Bạn có thể thấy hữu ích khi tách hình thành lát cắt khỏi việc chuyển nó sang list.__getitem__phương thức ( đó là những gì dấu ngoặc vuông làm ). Ngay cả khi bạn không quen với nó, nó sẽ giữ cho mã của bạn dễ đọc hơn để những người khác có thể phải đọc mã của bạn có thể dễ dàng hiểu những gì bạn đang làm.

Tuy nhiên, bạn không thể chỉ định một số số nguyên được phân tách bằng dấu hai chấm cho một biến. Bạn cần sử dụng đối tượng lát:

last_nine_slice = slice(-9, None)

Đối số thứ hai None, là bắt buộc, để đối số thứ nhất được hiểu là startđối số nếu không nó sẽ là stopđối số .

Sau đó, bạn có thể truyền đối tượng lát vào chuỗi của mình:

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

islice

islicetừ mô-đun itertools là một cách khác có thể thực hiện để có được điều này. islicekhông lấy các đối số phủ định, vì vậy lý tưởng là iterable của bạn có một __reversed__phương thức đặc biệt - danh sách nào có - vì vậy trước tiên bạn phải chuyển danh sách của mình (hoặc lặp lại với __reversed__) reversed.

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

islice cho phép đánh giá lười biếng đường ống dữ liệu, vì vậy để cụ thể hóa dữ liệu, hãy chuyển nó đến một hàm tạo (như list):

>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]

Chữ viết tắt tinh thần của bạn rất hữu ích
Swanky Coder

40

9 yếu tố cuối cùng có thể được đọc từ trái sang phải bằng cách sử dụng numlist [-9:] hoặc từ phải sang trái bằng numlist [: - 10: -1], như bạn muốn.

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

Dưới đây là một số tùy chọn để nhận các mục "đuôi" của một lần lặp:

Được

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

Sản phẩm chất lượng

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

Chúng tôi nhận được đầu ra sau bằng bất kỳ tùy chọn nào sau đây:

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

Chi tiết

  • A. Cắt lát Python truyền thống vốn có của ngôn ngữ. Tùy chọn này hoạt động với các chuỗi như chuỗi, danh sách và bộ dữ liệu. Tuy nhiên, loại cắt này không hoạt động trên các trình vòng lặp , ví dụ iter(iterable).
  • B. Một itertoolscông thức . Nó được khái quát hóa để làm việc trên bất kỳ lần lặp nào và giải quyết vấn đề lặp trong giải pháp cuối cùng. Công thức này phải được thực hiện thủ công vì nó không được bao gồm chính thức trong itertoolsmô-đun.
  • C. Nhiều công thức nấu ăn, bao gồm công cụ sau (B), đã được triển khai thuận tiện trong các gói của bên thứ ba. Cài đặt và nhập các thư viện này cản trở việc thực hiện thủ công. Một trong những thư viện này được gọi là more_itertools(cài đặt qua > pip install more-itertools); thấy more_itertools.tail.
  • D. Một thành viên của itertoolsthư viện. Lưu ý, itertools.islice không hỗ trợ cắt lát âm .
  • E. Một công cụ khác được thực hiện trong more_itertoolsđó khái quát hóa itertools.isliceđể hỗ trợ cắt lát âm; thấy more_itertools.islice_extended.

Tôi sử dụng cái nào?

Nó phụ thuộc . Trong hầu hết các trường hợp, cắt (tùy chọn A, như được đề cập trong các câu trả lời khác) là tùy chọn đơn giản nhất vì nó được tích hợp vào ngôn ngữ và hỗ trợ hầu hết các loại lặp. Đối với các trình vòng lặp tổng quát hơn, sử dụng bất kỳ tùy chọn còn lại nào. Lưu ý, tùy chọn C và E yêu cầu cài đặt thư viện của bên thứ ba, một số người dùng có thể thấy hữu ích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.