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

List Python:在另一个列表的成员中查找列表(按顺序),list,python,List,Python,如果我有这个: a='abcdefghij' b='de' 然后在a中找到b: b in a => True 有没有办法用列表做类似的事情? 像这样: a=list('abcdefghij') b=list('de') b in a => False “False”的结果是可以理解的——因为它正确地寻找元素“de”,而不是(我碰巧希望它做的事情)“d”后跟“e” 这是我的作品,我知道: a=['a', 'b', 'c', ['d', 'e'], 'f', 'g', 'h']

如果我有这个:

a='abcdefghij'
b='de'
然后在a中找到b:

b in a => True
有没有办法用列表做类似的事情? 像这样:

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

b in a => False 
“False”的结果是可以理解的——因为它正确地寻找元素“de”,而不是(我碰巧希望它做的事情)“d”后跟“e”

这是我的作品,我知道:

a=['a', 'b', 'c', ['d', 'e'], 'f', 'g', 'h']
b=list('de')
b in a => True
我可以压缩数据以得到我想要的——但是有没有一种简单的python方法可以做到这一点

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

如果有帮助的话,我有一个列表:这些列表表示有向图中从node-1到node-x的所有可能路径(访问节点列表):我想“因子”出任何更长路径中的公共路径。(因此,寻找所有不可约的“原子”路径,它们构成所有较长的路径)

相关的

因此,如果您不关心子集的显示顺序,可以执行以下操作:

a=list('abcdefghij')
b=list('de')
set(b).issubset(set(a))

True
澄清后编辑:如果您需要保留顺序,并且列表中的字符确实与您的问题相同,您可以使用:

''.join(a).find(''.join(b)) > 0

不知道您的应用程序有多复杂,但对于列表中的模式匹配,它非常智能且易于使用。

不知道这是否是一个非常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:])

较短的解是在这里提供的,但它遇到的问题与“代码> SET”一样,不考虑元素的顺序。

更新:
受MAK的启发,我引入了更简洁清晰的代码版本

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

我怀疑有更多的python方法,但至少它能完成任务:

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))

使用列表的字符串表示法并删除方括号。:)


编辑:对,有误报。。。e、 g.
是子列表([1],[11])
。蹩脚的回答。:)

我认为这会更快-它使用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)
请注意,这将返回子列表在列表中的位置,而不仅仅是
True
False
。如果您只需要一个
bool
,您可以使用:

def is_sublist(sub, bigger): 
    return find_sublist(sub, bigger) >= 0

我对已接受的解决方案、我以前的解决方案和带有索引的新解决方案进行了计时。有指数的那个显然是最好的

编辑:我为nosklo的解决方案计时,它甚至比我想到的要好得多。:)

以秒为单位的输出:

4.51677298546

4.5824368

1.87861895561


0.357429027557

这应该适用于任何一对列表,保留顺序。 正在检查b是否是a的子列表

def是子列表(b,a):
如果len(b)>len(a):
返回错误
如果a==b:
返回真值
i=0


虽然我很感谢——但实际上我确实需要保持秩序,我恐怕——我会更新问题以澄清这一点。多亏了这篇文章和我今天学到的另一篇文章“join()”!欢迎在Python邮件列表上讨论这个问题:这是非常有希望的(我看到它将列表“展平”为字符串)-但是在我的例子中,列表成员本身并不总是单个字符[事实上它们是数字]-如果我像这样折叠它们,我可能会丢失信息:我的错误是过分简化了问题!我可能会考虑用零填充数字,这样它们都是固定大小的元素。谢谢。如果你先把数字转换成带分隔符的str,比如:'.join([str(i)代表b中的i])。join([str(i)代表a中的i]),这会在[1,7,8]中为
[2,4]增加
,并且会在['why','hello']
中为
['qqhe','lloqq']返回不真实的答案。请参阅上面的评论。。。我没有改变答案,因为OP已经接受了一个…感谢链接-可能是一个小OTT为我想要的,但会检查出来。干杯这对我来说很好-很好地写的有意义。谢谢[我对Python太陌生了,不知道“Pythonic”到底是什么意思,但如果我是个赌徒,我敢打赌这就是Pythonic]哦,我刚刚把代码缩短了一点。试试这个新版本。如果它不适合你(或者我制造了一个bug=),你可以坚持使用旧的。由于递归,你正在构建大量的b副本,这是你的解决方案的一个明显缺点。假设您有一个包含一百万个条目的列表,并且您搜索的子列表显示在最末尾。希望您的列表不要太大,因为它会创建大约个len(b)列表。(len(b)/2+len(b)/2)。这对我的列表来说是可以的-不超过5-10项。我现在要继续看那个老顽皮鬼,不过我以后可能会看一看。干杯很好-虽然在我的例子中,我需要预处理我的项目以确保它们都是相同的长度-否则从string->list返回(我实际上需要返回一个'index'方法以及我的imp的True | False)。这通常是误报。尼斯:事实上差别很大+1用于计时。这个解决方案是最佳形式的性能视图,但我更喜欢我的,因为它看起来更清晰。这是一个相当C-方式,然后蟒蛇。但是我很高兴Python允许这两种方式)我不知道你怎么样,但我今晚睡了一会儿)由于递归限制,我的解决方案对这么长的列表不起作用。我甚至开始想象Python中有尾部递归优化!!当然,没有什么可以自己调用的。Fix
是\u sublist\u copyrist
,但不是另一个函数。使较小的
列表
不仅仅是一个元素,可能会更多地揭示解决方案的相对速度。尝试类似于
范围(1900099999)
的方法,而不是
[99999]
。我也对这一次计时。。。你打败了我,nosklo.)有一个小错误:返回的索引(当实际找到子字符串时)是o
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)
def is_sublist(sub, bigger): 
    return find_sublist(sub, bigger) >= 0
def is_sublist_index(a, b):
    if not a:
        return True

    index = 0
    for elem in b:
        if elem == a[index]:
            index += 1
            if index == len(a):
                return True
        elif elem == a[0]:
            index = 1
        else:
            index = 0

    return False

def is_sublist(a, b):
    return str(a)[1:-1] in str(b)[1:-1]

def is_sublist_copylist(a, b):
    if a == []: return True
    if b == []: return False
    return b[:len(a)] == a or is_sublist_copylist(a, b[1:])

from timeit import Timer
print Timer('is_sublist([99999], range(100000))', setup='from __main__ import is_sublist').timeit(number=100)
print Timer('is_sublist_copylist([99999], range(100000))', setup='from __main__ import is_sublist_copylist').timeit(number=100)
print Timer('is_sublist_index([99999], range(100000))', setup='from __main__ import is_sublist_index').timeit(number=100)
print Timer('sublist_nosklo([99999], range(100000))', setup='from __main__ import sublist_nosklo').timeit(number=100)
def is_sublist(b,a): 

    if len(b) > len(a):
        return False    

    if a == b:
        return True    

    i = 0
    while i <= len(a) - len(b):
        if a[i] == b[0]:
            flag = True
            j = 1
            while i+j < len(a) and j < len(b):
                if a[i+j] != b[j]:
                    flag = False
                j += 1
            if flag:
                return True
        i += 1
    return False