繁体   English   中英

在列表中查找连续值

[英]Finding consecutive values within a list

我有一个值列表:

a = [1,3,4,5,2]

我现在想要以下功能:

does_segment_exist(a, [1,3,4]) #True
does_segment_exist(a, [3,4,5]) #True
does_segment_exist(a, [4,5,2]) #True
does_segment_exist(a, [1,4,5]) #False
does_segment_exist(a, [1,3]) #True
does_segment_exist(a, [1,4]) #False

因此,必须按连续顺序找到这些值。

我有在Python 3中执行此操作的聪明方法吗?

您可以使用滚动窗口迭代器,在这种情况下,它来自itertools文档的旧版本:

from itertools import islice

def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result
    for elem in it:
        result = result[1:] + (elem,)
        yield result

def does_segment_exist(iterable, sublist):
    return tuple(sublist) in window(iterable, len(sublist))

print(does_segment_exist([1,3,4,5,2], [3,4,5]))

如果只需要它来处理列表,而不需要迭代,则可以使用:

def does_segment_exist(seq, sublist):
    # seq and sublist must both be lists
    n = len(sublist)
    return sublist in (seq[i:i+n] for i in range(len(seq) + 1 - n))

雷蒙德提到的方法的基本实现:

def does_segment_exist(seq, sublist):
    first = sublist[0]
    i = 0
    n = len(sublist)
    while True:
        try:
            i = seq.index(first, i)
        except ValueError:
            return False
        if sublist == seq[i:i+n]:
            return True
        i += 1

print(does_segment_exist([1,3,4,5,2], [3,4,5]))

此方法的优点是,不必为直到第一个匹配项的每个索引切片,而只需对与该段中第一个值的匹配项对应的索引进行切片。

有很多方法可以做到这一点,它们对于子串搜索算法都是同构的。

最简单的方法是使用list.index()来天真的搜索,以找到一个共同的起点,然后使用切片来检查完全匹配。 如果没有匹配项,请重复搜索,直到到达列表末尾。

这适用于Python 2.5及更高版本:

def does_segment_exist(sequence, segment):
    n, m = len(sequence), len(segment)
    return any(segment == sequence[i:i+m] for i in range(n+1-m))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM