使用Python在另一个列表中搜索一个列表的值 [英] Searching values of a list in another List using Python

查看:670
本文介绍了使用Python在另一个列表中搜索一个列表的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试查找列表的子列表.这意味着如果list1说[1,5]在list2中说[1,4,3,5,6],则它应该返回True.到目前为止,我的情况是这样:

I'm a trying to find a sublist of a list. Meaning if list1 say [1,5] is in list2 say [1,4,3,5,6] than it should return True. What I have so far is this:

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

这将是正确的,但我仅在list1以相应顺序位于list2中时才尝试返回True.因此,如果list2为[5,2,3,4,1],则应返回False.我一直在考虑使用<比较list1的索引值的思路.但我不确定.

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)的位置;像这里一样,通过第二个arg调用它,它开始在列表中的该位置查找.如果index找不到所需的内容,则会引发ValueError异常.

The index method of list L2 returns the position at which the first argument (num) is found in the list; called, like here, with a second arg, it starts looking in the list at that position. If index does not find what it's looking for, it raises a ValueError exception.

因此,此代码使用此方法在L2中按顺序查找L1的每个项目num.第一次需要从位置0开始寻找;接下来的每次,它都需要从找到上一个项目的最后一个位置之后的位置开始寻找,即last_found + 1(因此,开始时,我们必须将last_found = -1设置为第一次从位置0开始寻找).

So, this code uses this approach to look for each item num of L1, in order, inside L2. The first time it needs to start looking from position 0; each following time, it needs to start looking from the position just after the last one where it found the previous item, i.e. last_found + 1 (so at the start we must set last_found = -1 to start looking from position 0 the first time).

如果以这种方式找到了L1中的每个项目(即在找到前一个项目的位置之后在L2中找到了项目),则两个列表均满足给定条件,并且代码返回True.如果找不到L1的任何项,则代码将捕获产生的ValueError异常,并仅返回False.

If every item in L1 is found this way (i.e. it's found in L2 after the position where the previous item was found), then the two lists meet the given condition and the code returns True. If any item of L1 is ever not-found, the code catches the resulting ValueError exception and just returns False.

另一种方法是在两个列表上使用 iterators ,这可以通过iter内置函数来形成.您可以通过调用内置的next来高级"迭代器.如果没有下一项",即迭代器用尽,这将引发StopIteration.如果适用,您还可以在迭代器上使用for以获得更平滑的界面.使用iter/next想法的低级方法:

A different approach would be to use iterators over the two lists, that can be formed with the iter built-in function. You can "advance" an iterator by calling built-in next on it; this will raise StopIteration if there is no "next item", i.e., the iterator is exhausted. You can also use for on the iterator for a somewhat smoother interface, where applicable. The low-level approach using the iter/next idea:

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 -将内部循环设为for maybe in i2可以确保内部循环不会每次都从头开始.继续寻找最后停下来的地方.对于for lookfor in L1:,外循环也可能如此,因为它没有重新启动"的问题.

In fact, the only crucial use of iter here is to get i2 -- having the inner loop as for maybe in i2 guarantees the inner loop won't start looking from the beginning every time, but, rather, it will keep looking where it last left off. The outer loop might as well for for lookfor in L1:, since it has no "restarting" issue.

键是循环的else:子句,当且仅当该循环未被break中断而是自然退出时才触发.

Key, here, is the else: clause of loops, which triggers if, and only if, the loop was not interrupted by break but rather exited naturally.

进一步研究这个想法,我们再次想到了in运算符,只需使用迭代器,也可以使该运算符继续到上一个中断的地方.大大简化:

Working further on this idea we are again reminded of the in operator, which also can be made to continue where it last left off simply by using an iterator. Big simplification:

i2 = iter(L2)
for lookfor in L1:
  if lookfor not in i2:
    return False
# no more items to look for == all good!
return True  

但是现在我们意识到,这正是短路anyall内置的短路蓄电池"功能所抽象的模式,所以...:

But now we recognize that is exactly the patter abstracted by the short-circuiting any and all built-in "short-circuiting accumulator" functions, so...:

i2 = iter(L2)
return all(lookfor in i2 for lookfor in L1)

我相信这几乎就是您所能获得的.这里剩下的唯一非基本元素是:您只需一次使用一次iter(L2)即可确保in运算符(本质上是一个内部循环)不会从头开始搜索,而是继续每个搜索从上次停止的时间开始.

which I believe is just about as simple as you can get. The only non-elementary bit left here is: you need to use an iter(L2) explicitly, just once, to make sure the in operator (intrinsically an inner loop) doesn't restart the search from the beginning but rather continues each time from where it last left off.

这篇关于使用Python在另一个列表中搜索一个列表的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆