【问题标题】:Check if list is sublist of another list and the elements are in the same order检查列表是否是另一个列表的子列表并且元素的顺序相同
【发布时间】:2021-12-26 18:36:18
【问题描述】:
#sub list test 1
a = [1,1,2]
b = [0, 1,1,1,2,1]

#sub list test 2
c = [4,5]
d = [2,3,4,5,6]
if all(i in a for i in b):
   print("Yes I have all the elements but not sure about their order :( ")

我已经尝试过all() 或使用collections 模块中的counter()。我似乎也无法弄清楚如何检查他们的订单。

【问题讨论】:

  • 如果第一个元素匹配,还剩下什么要做?如果他们不这样做,还能做什么?
  • 这能回答你的问题吗? Checking if list is a sublist
  • @sj95126 - 不,那里的解决方案不检查订单。您可以在上面的第一个测试中测试(a 和 b)
  • @Danny:该线程中有很多解决方案。有些不检查顺序,而 cmets 反映了这一点。
  • 子列表已经暗示了相同的顺序。所以不清楚你在说什么。

标签: python


【解决方案1】:

这将检查所有长度为 a 的子列表,如果在 b 中找到 a,则返回 True

不确定顺序:

def isSublist(a,b):
    #checking all unique elements and their count
    for i in set(a):
        if i not in b or a.count(i) > b.count(i):
             return False
    return True

确定订单:

def isSublist(a,b):
    for i in range(len(b)-len(a)+1):
        if b[i:i+len(a)] == a:
            return True
    return False

【讨论】:

  • 看起来不错。我会做更多的测试,让你知道。谢谢。
  • 是的,我做了更多的测试,它按预期工作。欢呼
  • 您的第一个代码可能是return Counter(a) <= Counter(b)
  • @Dennis 我们无法比较 2 个 Counter 对象,它会给出类型错误,请检查您自己一次
  • 啊,我明白了,该功能是在 Python 3.10 中添加的,在之前的版本中无法使用。
【解决方案2】:

在大多数情况下,当列表元素具有普通类型时,您可以先将它们转换为str,然后再进行

"#".join(sublist) in "#".join(list)

其中#list 中没有出现的符号

编辑,正如 no comment 指出的那样,确实存在一个错误 - 如果最后一个子列表元素是最后一个列表元素的前缀。与第一个元素后缀相同。我们可以通过在开头/结尾添加某种哨兵来管理它,所以正确的解决方案是

"#".join([""] + sublist + [""]) in "#".join([""] + list + [""])

【讨论】:

  • 如果列表元素不是strjoin 将不起作用
  • @match 我在回答中触及了这一点;)问题有时很简单 str 方法不够(例如,对于具有自定义 eq 的类),这就是我最后提供的原因算法步骤。
【解决方案3】:

您可以通过b 上的迭代器检查a 的成员资格来使用 all():

a = [1,1,2]
b = [0, 1,1,1,2,1]

r = all(n in ib for ib in [iter(b)] for n in a)
print(r) # True

它还会以相同的相对顺序(不连续)找到匹配项:

a=[1,2,1]
b=[1,2,3,1]
r = all(n in ib for ib in [iter(b)] for n in a)
print(r) # True

它是如何工作的:

  • 每次执行 n in ib 时,ib 迭代器都会前进到 b 中的下一个匹配值。
  • 遍历a 的所有值将在每次匹配检查后依次匹配b 的其余部分
  • 如果ib 在到达a 的末尾之前已用尽,则元素未全部存在或它们的顺序不匹配

如果您正在寻找连续匹配,您可以在生成相应长度子列表的生成器上使用in 运算符:

a = [1,1,2]
b = [0, 1,1,1,2,1]

r = a in (b[i:i+len(a)] for i in range(len(b)-len(a)+1))
print(r) # True

【讨论】:

  • 感谢您的回答和解释。因为我是 Python 新手,所以我需要按照自己的节奏完成它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 2021-01-04
相关资源
最近更新 更多