如果我有这个:
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)
我认为这会更快 - 它使用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)
请注意,这将返回列表中子列表的位置,而不仅仅是True
或False
.如果你只想要一个,bool
你就可以使用它:
def is_sublist(sub, bigger):
return find_sublist(sub, bigger) >= 0
Run Code Online (Sandbox Code Playgroud)
不知道这是非常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切片创建视图,而不是副本.如果遇到性能或递归限制问题,则应使用不带递归的解决方案.