Python 如何检查列表中的元素是否位于给定元素之后
我有一个列表,想检查列表中是否存在给定的序列。Python 如何检查列表中的元素是否位于给定元素之后,python,arrays,list,sorting,sequence,Python,Arrays,List,Sorting,Sequence,我有一个列表,想检查列表中是否存在给定的序列。例如,给定的序列是'a','h','z',列表是l=['a','b','h','g','z']。假设在列表中z在h之后,在a之后,我需要代码返回真值 def check_for_a_h_z(顺序): zip格式的return('a','h','z')(seq,seq[1:],seq[2:] 只有当'a'、'h'、'z'紧跟在一起时,代码才会返回true。封套背面暴力尝试两个序列的通用解决方案: 从输入导入序列开始 def有序_包含(s1:序列,s2
例如,给定的序列是
'a','h','z'
,列表是l=['a','b','h','g','z']
。假设在列表中z在h之后,在a之后,我需要代码返回真值
def check_for_a_h_z(顺序):
zip格式的return('a','h','z')(seq,seq[1:],seq[2:]
只有当
'a'、'h'、'z'紧跟在一起时,代码才会返回true。封套背面暴力尝试两个序列的通用解决方案:
从输入导入序列开始
def有序_包含(s1:序列,s2:序列)->bool:
'''
>>>有序_包含('ahz'、'abhgz')
真的
>>>有序_包含(“”,'asdlkjf')
真的
>>>有序_包含('lol','lofi')
假的
'''
i=0
对于s1中的v:
尝试:
i=s2.指数(v,i)
除值错误外:
返回错误
返回真值
这里有一种使用递归的方法:
def list_sequence_recursive(test, lst):
if len(test) == 1:
return test[0] in lst
else:
if test[0] in lst:
idx = lst.index(test[0]) + 1 # don't send the matched element
return list_sequence_recursive(test[1:], lst[idx:])
else:
return False
test_sequence_recursive(['a', 'h', 'z'],
['a','b','h','g','z'])
# True
注意我们使用lst.index(test[0])+1
作为下一次迭代的开始索引,这样我们只发送匹配后的元素。如果您关闭了+1
,您将错误地将输入列表与匹配,例如['a','a','h']
,即使您只有一个'a'
例如,这将:
找到'a'
,然后使用参数['h','z']
和['b','h','g','z']
找到'h'
,然后用参数['z']
和['g','z']
找到'z'
并返回链上的True
这是一种有点直观的方法,但不是很通俗:
l=['a','b','h','g','z']
def check_for_a_h_z(seq):
if 'a' in seq:
ind=seq.index('a')
if 'h' in seq[ind:]:
ind2=seq.index('h')
if 'z' in seq[ind2:]:
return True
else:
return False
else:
return False
else:
return False
check_for_a_h_z(l)
如果在O(n)
最坏的情况下中的事物在seq
中是有序的,则返回True
:
def check_for_things(things,seq):
k = things[:]
for c in seq:
if c == k[0]:
k.pop(0)
if not k:
break
return not k # if you popped all from k you are done
print( check_for_things(list("ahz"), list('abhgz')))
print( check_for_things(list("ahiz"), list('abhgz')))
输出:
True
False
它还将为list(“ahz”)、list(“abhhhhhhhhgz”)
生成True
——忽略超级h
一个更优化的解决方案(建议的)是在列表末尾的任何位置使用弹出元素,因为剩余的列表
数据被移位了1-deque可以左键
(和右键
)在O(1)中:
请运行一个example@user10316146好的,我已经包括了你想要的例子。@PatrickArtner我想如果n=len(s1)和m=len(s2),那么它就是Θ(n+m)。如果我错了,请纠正我,我对算法的复杂性很马虎。我想如果len(s1)>len(s2):return False将是一个微不足道的优化,但我不会出于如此美观的原因把它放进去。:)@PatrickArtner最糟糕的情况是,除了s1的最后一个元素外,其他元素都在s2中,但最后一个元素不在s2中,对吗?在这种情况下,我们迭代所有s1,也遍历所有s2。对于从s1到s1的每一步,我们至少扫描s2的一个元素,直到len(s2)。这就是为什么我仍然认为这是最坏的情况Θ(n+m)。这就是我的想法。如果你要做k.pop(0)
,我建议使用一个而不是一个列表。@Aran Fey从列表前面弹出是昂贵的,同意。添加了一个deque版本。我非常喜欢这个被称为dup目标的问题。它适用于字符串、字符列表、字符串列表。
def better_check_for_things(things,seq):
k = deque(things)
for c in seq:
if c == k[0]:
k.popleft()
if not k:
break
return not k # if you popped all from k you are done
print( better_check_for_things(list("ahz"), list('abhgz')))
print( better_check_for_things(list("ahiz"), list('abhgz')))