我需要列表的最后 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[:]
(列表在 Python 3 中得到list.copy
和。)list.clear
您可能会发现将形成切片与将切片传递给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))
细节
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 需要安装第三方库,一些用户可能会觉得这很有用。