Python:在另一个列表的成员中查找列表(按顺序)

mon*_*nny 17 python list

如果我有这个:

a='abcdefghij'
b='de'
Run Code Online (Sandbox Code Playgroud)

然后这在一个:

b in a => True
Run Code Online (Sandbox Code Playgroud)

有没有办法用列表做类似的事情?像这样:

a=list('abcdefghij')
b=list('de')

b in a => False 
Run Code Online (Sandbox Code Playgroud)

'False'结果是可以理解的 - 因为它正确地寻找元素'de',而不是(我碰巧想要它做什么)'d'后跟'e'

这是有效的,我知道:

a=['a', 'b', 'c', ['d', 'e'], 'f', 'g', 'h']
b=list('de')
b in a => True
Run Code Online (Sandbox Code Playgroud)

我可以处理数据以获得我想要的东西 - 但是有一个简短的Pythonic方法吗?

澄清:我需要在这里保留排序(b = ['e','d'],应该返回False).

如果它有帮助,我所拥有的是列表列表:这些列表表示有向图中从节点1到节点-x的所有可能路径(访问节点列表):我想要"排除"常见路径任何更长的路径.(因此寻找所有不可缩短的"原子"路径,构成所有较长的路径).

有关

MAK*_*MAK 11

我怀疑有更多的pythonic方法,但至少它完成了工作:

l=list('abcdefgh')
pat=list('de')

print pat in l # Returns False
print any(l[i:i+len(pat)]==pat for i in xrange(len(l)-len(pat)+1))
Run Code Online (Sandbox Code Playgroud)


nos*_*klo 7

我认为这会更快 - 它使用C实现list.index来搜索第一个元素,并从那里开始.

def find_sublist(sub, bigger):
    if not bigger:
        return -1
    if not sub:
        return 0
    first, rest = sub[0], sub[1:]
    pos = 0
    try:
        while True:
            pos = bigger.index(first, pos) + 1
            if not rest or bigger[pos:pos+len(rest)] == rest:
                return pos
    except ValueError:
        return -1

data = list('abcdfghdesdkflksdkeeddefaksda')
print find_sublist(list('def'), data)
Run Code Online (Sandbox Code Playgroud)

请注意,这将返回列表中子列表的位置,而不仅仅是TrueFalse.如果你只想要一个,bool你就可以使用它:

def is_sublist(sub, bigger): 
    return find_sublist(sub, bigger) >= 0
Run Code Online (Sandbox Code Playgroud)


Ror*_*ick 6

不知道这是非常pythonic,但我会这样做:

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:])
Run Code Online (Sandbox Code Playgroud)

在这个讨论中提供了更短的解决方案,但是它遇到了与解决方案相同的问题set- 它没有考虑元素的顺序.

更新:
受到MAK的启发,我介绍了更简洁明了的代码版本.

更新:由于列表中的列表复制,此方法存在性能问题.此外,由于它是递归的,您可能会遇到长列表的递归限制.要消除复制,可以使用Numpy切片创建视图,而不是副本.如果遇到性能或递归限制问题,则应使用不带递归的解决方案.

  • 希望你的名单不会太大,因为它创造了大约.len(b)列表.(len(b)/ 2 + len(b)/ 2). (2认同)