检查一个列表是否以另一个列表的元素开头

15

检查列表开头是否完全由另一个列表的元素组成,最容易(最符合Python风格)的方法是什么?考虑以下示例:

li = [1,4,5,3,2,8]

#Should return true
startsWithSublist(li, [1,4,5])

#Should return false
startsWithSublist(list2, [1,4,3])

#Should also return false, although it is contained in the list
startsWithSublist(list2, [4,5,3])

我可以遍历这两个列表,但我觉得有更简单的方法。这两个列表永远不会包含相同的元素,并且第二个列表的长度始终小于或等于第一个列表的长度。要匹配的列表的长度是可变的。

在Python中如何实现?

2个回答

25
使用列表切片:
>>> li = [1,4,5,3,2,8]
>>> sublist = [1,4,5]
>>> li[:len(sublist)] == sublist
True

3
你可以使用all而不需要切片或创建另一个列表来实现这个功能:
def startsWithSublist(l,sub):
    return len(sub) <= l and all(l[i] == ele  for i,ele  in enumerate(sub))

如果您发现不匹配的元素,则会短路,或者如果所有元素都相同,则返回True,您还可以使用 itertools.izip

from itertools import izip
def startsWithSublist(l,sub):
    return len(sub) <= l and  all(a==b  for a,b in izip(l,sub))

1
请注意,如果子列表的长度超过序列并与其匹配到相同的长度,例如startsWithSublist([1,2,3],[1,2,3,4]),则您的基于索引的方法将会抛出异常。而您的第二种方法在这种情况下将返回True(尽管它可能不应该)。 (是的,我知道OP排除了这种情况,但仍然,这是切片没有的缺点。) - DSM
@DSM,添加了len(sub) <= l来处理这种情况。 - Padraic Cunningham
非常感谢您的回复。我喜欢上面答案的简洁性,但也看到了您解决方案的优点。然而,在这种情况下,内存利用率和性能并不重要,因为列表相当小(<= 5个条目),我更喜欢简单的解决方案。 - Daniel
1
@waza-ari,没错,切片是最简单的方法,如果你有大量数据,这将是一种更节省内存的方法。 - Padraic Cunningham
这句话应该是 len(sub) <= len(l) 吗? - Brian McCutchon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接