要确定列表是否是列表的子列表

时间:2018-01-15 05:23:02

标签: python python-3.x

list1=[1,3,8,10,23,8,8,10,23,3,8,10,23,3,8,10,23]
list2=[10,23,3]
cnt=list1.count(list2[0])
cnt1=1
j=0
while (cnt1<=cnt):
    list3=[]
    list3.append(list2[0])
    i=1
    k=list1.index(list2[0])
    while (i<len(list2)):
        list3.append(list1[k+i])
        i=i+1
    print (list3)    
    if (list2==list3):
        print ("list2 is a subset")
        j=j+1
    else:
        print ("list2 is not a subset")

    list1.remove(list2[0])    
    cnt1=cnt1+1    
print (list2,"occurs",j,"times")

我收到此错误。

Traceback (most recent call last):
  File "C:\Python26\Lib\idlelib\sublist.py", line 12, in <module>
    list3.append(list1[k+i])
IndexError: list index out of range"

3 个答案:

答案 0 :(得分:5)

你肯定过于复杂 - 至于你的策略究竟是什么并不明显。

这是一个你可以尝试和整合的简单算法:

  1. 获取list2
  2. 的长度
  3. 遍历list1,访问长度list2列表的切片(例如,第一个切片为[1, 3, 8],然后下一个切片为[3, 8, 10]
  4. 检查切片是否等于list2 - 如果是,则返回True(或将1添加到计数器)
  5. 如果到达列表末尾 - 结束

答案 1 :(得分:1)

您可以测试适当长度的所有list1切片与list2的相等。然后,您可以使用sum来获取出现次数:

list1 = [1,3,8,10,23,8,8,10,23,3,8,10,23,3,8,10,23]
list2 = [10,23,3]

l1, l2 = len(list1), len(list2)
num_occurrences = sum(list1[i:i+l2] == list2 for i in range(l1 - l2 + 1))
# 2

答案 2 :(得分:0)

这是一种可行的方法:

from collections import deque
from itertools import islice

list1=[1,3,8,10,23,8,8,10,23,3,8,10,23,3,8,10,23]

list2=[10,23,3]

size = len(list2)

# convert to a queue
items = deque(list1)

count = 0

# iterate until no more sublists can be extracted
while len(items) >= size:
    current = list(islice(items, 0, size))

    # if the current sublist is equal to list1, increment count
    if current == list2:
        count += 1

    # pop the first element from this queue, ready for next sublist
    items.popleft()

print (list2,"occurs",count,"times")

哪个输出:

[10, 23, 3] occurs 2 times

上述代码的方法:

  • list1转换为collections.deque对象,该对象可以在O(1)时间内从正面弹出对象。这是代码中的items
  • 存储count个相同的列表,其中包含list2
  • 检查current子列表(n中的第一个items元素作为列表)是否等于list2。如果相等则增加计数。
  • 使用items弹出popleft()中的第一项,为下一个子列表做好准备。因此,如果我的列表为[1, 2, 3, 4],则在处理[1, 2, 3]后,从1弹出items,然后检查下一个子列表[2, 3, 4]
  • 继续执行此过程,直到无法提取size个子列表。然后你可以在最后打印出计数。