如果还没有被要求,我会感到惊讶。
我们说我有一个数组[5,6,7,29,34]
,我想检查序列5,6,7
是否出现在它(它做了)。订单很重要。
我该怎么做?
答案 0 :(得分:4)
只是为了好玩,这是一个快速(非常快)和脏(非常脏)的解决方案(有点缺陷,所以不要真的使用它):
>>> str([5,6,7]).strip('[]') in str([5,6,7,29,34])
True
RightWay™可能会使用list.index()来查找第一个元素的候选匹配项,然后验证与切片和列表相等的完全匹配:
>>> def issubsequence(sub, seq):
i = -1
while True:
try:
i = seq.index(sub[0], i+1) # locate first character
except ValueError:
return False
if seq[i : i+len(sub)] == sub: # verify full match
return True
>>> issubsequence([5, 6, 7], [5,6,7,29,34])
True
>>> issubsequence([5, 20, 7], [5,6,7,29,34])
False
编辑:OP在评论中澄清,子序列必须按顺序排列,但不必处于连续位置。这有一个不同的,更复杂的解决方案,已在这里得到解答:How do you check if one array is a subsequence of another?
答案 1 :(得分:2)
这是一个很好的解决方案:
def is_sublist(a, b):
if not a: return True
if not b: return False
return b[:len(a)] == a or is_sublist(a, b[1:])
如Stefan Pochmann所述,这可以改写为:
def is_sublist(a, b):
return b[:len(a)] == a or bool(b) and is_sublist(a, b[1:])
答案 2 :(得分:0)
这是一个对任何可迭代对象都有效(高效!)的解决方案:
import collections
import itertools
def consume(iterator, n=None):
"""Advance the iterator n-steps ahead. If n is none, consume entirely."""
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
def is_slice(seq, subseq):
"""Returns whether subseq is a contiguous subsequence of seq."""
subseq = tuple(subseq) # len(subseq) is needed so we make it a tuple.
seq_window = itertools.tee(seq, n=len(subseq))
for steps, it in enumerate(seq_window):
# advance each iterator to point to subsequent values in seq.
consume(it, n=steps)
return any(subseq == seq_slice for seq_slice in izip(*seq_window))
consume
来自itertools recipes。