用Pythonic方式获取列表尾部?

7 投票
3 回答
8068 浏览
提问于 2025-04-16 05:18
from random import randrange
data = [(randrange(8), randrange(8)) for x in range(8)]

我们需要检查第一个项目是否等于尾部的某个项目。我很好奇,有没有更简单的方法来做到这一点,而不需要把尾部的项目复制到一个新列表里?请考虑到这段代码会在比如说 update() 方法中执行很多次,所以它必须尽可能快。

使用一个额外的列表(我想这会浪费不必要的内存):

head = data[0]
result = head in data[1:]

好吧,这里有另一种方法(太繁琐了):

i = 1
while i < len(data):
    result = head == data[i]
    if result:
        break
    i+=1

用最符合 Python 风格的方法来解决这个问题是什么?谢谢。

3 个回答

-1

这是个老问题,不知道什么时候开始有的:用星号来解包。

>>> t = (1,2,3)
>>> *_, last = t
>>> t
(1, 2, 3)
>>> last
3

而且这个用法很灵活,因为它的语法不仅仅局限于尾部:

>>> t = (1,2,3,4)
>>> first, *_, last = t
>>> first
1
>>> last
4
>>> t
(1, 2, 3, 4)

原帖问的是获取尾部的“Pythonic”方式。不确定这是否是Python社区的选择,但这确实是Python特有的一种语法(根据我所知道的情况)。

8

Nick D的回答更好

可以使用 islice。它不会复制列表,而是把你的第二种(虽然优雅但有点啰嗦)解决方案嵌入到一个C模块中。

import itertools

head = data[0]
result = head in itertools.islice(data, 1, None)

这是一个演示:

>>> a = [1, 2, 3, 1]
>>> head = a[0]
>>> tail = itertools.islice(a, 1, None)
>>> head in tail
True

请注意,你只能遍历一次。如果你只是想检查头部是否在尾部,并且你担心内存使用,那么我觉得这是最好的选择。

6

替代的方法,

# 1
result = data.count(data[0]) > 1


# 2
it = iter(data)
result = next(it) in it

撰写回答