如何在Python中获得列表的最后一项?

我需要一个列表的最后9个数字,我相信有一种方法可以用切片来做,但我似乎不能得到它。我可以像这样得到前9个

num_list[0:9]
564862 次浏览

负索引将从列表的末尾开始计数,因此:

num_list[-9:]

你可以使用负整数和切片运算符。下面是一个使用python CLI解释器的示例:

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

最后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]

切片

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

Slice表示法从列表(或任何其他支持它的序列,如字符串)中获取最后9个元素,看起来像这样:

num_list[-9:]

当我看到这个时,我把括号里的部分读为“从末尾到末尾的第9个部分”。(实际上,我把它缩写为“-9,on”)

解释:

完整的符号是

sequence[start:stop:step]

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

list_copy = sequence[:]

清除它们的方法是:

del my_list[:]

(列表在python3中获得list.copylist.clear。)

给你的切片起一个描述性的名字!

你可能会发现将切片的形成与将其传递给list.__getitem__方法(这就是方括号的作用)分开是很有用的。即使您不是新手,它也可以使您的代码更具可读性,以便其他可能需要阅读您的代码的人可以更容易地理解您在做什么。

但是,不能将一些用冒号分隔的整数赋值给变量。你需要使用slice对象:

last_nine_slice = slice(-9, None)

第二个参数None是必需的,因此第一个参数被解释为start参数否则它将是stop参数

然后你可以将slice对象传递给你的序列:

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

islice

来自itertools模块的islice是另一种可能的性能方法。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]

下面是获取可迭代对象“尾部”项的几个选项:

鉴于

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需要安装第三方库,一些用户可能会发现这很有用。