try:
last_found = -1
for num in L1:
last_found = L2.index(num, last_found + 1)
return True
except ValueError:
return False
列表L2的 index
方法返回在列表中找到第一個參數( num
)的位置;就像這裏所說的那樣,帶著第二個參數,它開始在那個位置查找列表。如果 index
找不到要查找的內容,則會引發 ValueError
異常。
因此,此代碼使用此方法按順序在 L2
內部查找 L1
的每個項目
num
。第一次需要從位置0開始尋找;每次接下來的時間,它需要從最後一個找到前一個項目的位置開始查找,即
last_found + 1
(所以在開始時我們必須設置 last_found =
-1
第一次從位置0開始查看)。
如果L1中的每個項目都是以這種方式找到的(即,在找到前一個項目的位置之後它在L2中找到),那麽這兩個列表符合給定條件並且代碼返回
True
。如果找不到L1的任何項目,代碼會捕獲產生的 ValueError
異常,並返回 False
。
另一種方法是在兩個列表中使用 iterators ,它們可以用 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
或者更高一點:
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
實際上,這裏 iter
的唯一關鍵用途是獲取i2 -
將內部循環作為用於i2中的內容
保證內部循環不會從每次都會開始,但是,它會繼續尋找最後一次離開的位置。因為它沒有“重新啟動”問題,所以
中的可以用於外部循環。
這裏的關鍵是循環的 else:
子句,當且僅當循環未被 break
中斷而是自然退出時觸發。
進一步研究這個想法,我們再次提醒運算符中的,它也可以通過簡單地使用叠代器繼續執行。大大簡化:
i2 = iter(L2)
for lookfor in L1:
if lookfor not in i2:
return False
# no more items to look for == all good!
return True
但現在我們認識到,這正是短路所有
和所有
內置的“短路累加器”功能所提取的模式,所以......:
i2 = iter(L2)
return all(lookfor in i2 for lookfor in L1)
我相信這只是你可以得到的簡單而已。這裏剩下的唯一非基本位是:你需要明確地使用一個
iter(L2)
來確保運算符中的(本質上是一個內部循環)不從一開始就重新開始搜索,而是每次從最後一次停止的地方繼續搜索。