一千萬個為什麽

搜索

使用Python在另一個List中搜索列表的值

我正在嘗試查找列表的子列表。意思是如果list1說[1,5]在list2中說[1,4,3,5,6],它應該返回True。到目前為止我所擁有的是:

for nums in l1:
    if nums in l2:
        return True
    else:
        return False

This would be true but I'm trying to return True only if list1 is in list2 in the respective order. So if list2 is [5,2,3,4,1], it should return False. I was thinking along the lines of comparing the index values of list1 using < but I'm not sure.

最佳答案

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)來確保運算符中的(本質上是一個內部循環)不從一開始就重新開始搜索,而是每次從最後一次停止的地方繼續搜索。

轉載註明原文: 使用Python在另一個List中搜索列表的值