我需要列表的最后 9 个数字,我确信有一种方法可以通过切片来实现,但我似乎无法得到它。我可以这样得到前 9 个:

num_list[0:9]

任何帮助都会很棒。

有帮助吗?

解决方案

您可以使用负整数与该切片运算符。下面是使用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]

重要的行是a[-9:]

其他提示

负指数将从列表的末尾数,所以:

num_list[-9:]

切片

Python 切片是一种非常快的操作,它是快速访问部分数据的便捷方法。

从列表(或支持它的任何其他序列,如字符串)中获取最后九个元素的切片表示法如下所示:

num_list[-9:]

当我看到这一点时,我将括号中的部分读取为“从末端到末端的第9个”。 (实际上,我将其缩写为“ -9,on”)

解释:

完整的记号是

sequence[start:stop:step]

但冒号告诉 Python 你给它的是一个切片,而不是一个常规索引。这就是为什么在 Python 2 中复制列表的惯用方法是

list_copy = sequence[:]

清除它们是:

del my_list[:]

(列表得到 list.copylist.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__ 特殊方法 - 列出 有 - 所以你必须首先传递你的列表(或可迭代的 __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))

细节

  • A。传统Python 切片 是语言固有的。此选项适用于 序列 例如字符串、列表和元组。然而,这种切片不适用于 迭代器, ,例如 iter(iterable).
  • B.一个 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 需要安装第三方库,某些用户可能会发现这很有用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top