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