我正试图找到列表的子列表.意思是如果list1说[1,5]在list2中说[1,4,3,5,6],它应该返回True.到目前为止我所拥有的是:
for nums in l1:
if nums in l2:
return True
else:
return False
Run Code Online (Sandbox Code Playgroud)
这是真的,但我只是在list1在相应的顺序中的list2中时才尝试返回True.因此,如果list2是[5,2,3,4,1],它应该返回False.我正在考虑使用<比较list1的索引值,但我不确定.
try:
last_found = -1
for num in L1:
last_found = L2.index(num, last_found + 1)
return True
except ValueError:
return False
Run Code Online (Sandbox Code Playgroud)
index列表L2 的方法返回列表中第一个参数(num)的位置; 像这里一样,用第二个arg调用,它开始查看该位置的列表.如果index找不到它想要的东西,它会引发ValueError异常.
因此,该代码使用了这种方法来寻找每个项目num的L1,按顺序里面L2.第一次需要从0位开始寻找; 每个下一次,它需要从最后一个位置找到前一个项目的位置开始查看,即last_found + 1(因此在开始时我们必须设置last_found = -1为从第一次开始从位置0开始).
如果L1中的每个项都以这种方式被找到(即它在找到前一项的位置之后的L2中找到),那么这两个列表满足给定条件并且代码返回True.如果找不到任何L1项,代码将捕获结果ValueError异常并返回False.
另一种方法是在两个列表上使用迭代器,这可以使用iter内置函数形成.你可以通过调用内置函数来"推进"迭代器next; StopIteration如果没有"下一个项目",即迭代器用尽,这将会提高.for如果适用,您还可以在迭代器上使用更平滑的接口.使用iter/next想法的低级方法:
i1 = iter(L1)
i2 = iter(L2)
while True:
try:
lookfor = next(i1)
except StopIteration:
# no more items to look for == all good!
return True
while True:
try:
maybe = next(i2)
except StopIteration:
# item lookfor never matched == nope!
return False
if maybe == lookfor:
break
Run Code Online (Sandbox Code Playgroud)
或者,更高一级:
i1 = iter(L1)
i2 = iter(L2)
for lookfor in i1:
for maybe in i2:
if maybe == lookfor:
break
else:
# item lookfor never matched == nope!
return False
# no more items to look for == all good!
return True
Run Code Online (Sandbox Code Playgroud)
事实上,iter这里唯一关键的用途是获得i2 - 内部循环for maybe in i2保证内部循环不会每次从头开始查看,而是相反,它将继续查看它最后停止的位置.外环也可以for lookfor in L1:,因为它没有"重启"问题.
键,这里是else:循环的子句,当且仅当循环没有被中断break而是自然退出时触发.
进一步研究这个想法,我们再次提醒in操作员,也可以通过使用迭代器继续它最后停止的地方.大简化:
i2 = iter(L2)
for lookfor in L1:
if lookfor not in i2:
return False
# no more items to look for == all good!
return True
Run Code Online (Sandbox Code Playgroud)
但现在我们认识到这正是由短路any和all内置"短路累加器"功能提取的模式,所以...:
i2 = iter(L2)
return all(lookfor in i2 for lookfor in L1)
Run Code Online (Sandbox Code Playgroud)
我认为这就像你能得到的一样简单.这里留下的唯一非基本位是:你需要使用一个iter(L2)显式的,只需要一次,以确保in操作符(本质上是一个内部循环)不会从头重新开始搜索,而是每次从最后一次离开的地方继续关闭.