解决一个列表是否充当另一个列表的子列表

时间:2018-08-04 20:41:07

标签: python python-3.x list

我已经在这个问题上工作了一段时间,感觉完全迷失了。看来这是非常基本的,但似乎无法解决。我并不是真正在寻找确切的答案,只是我在正确的轨道上。我刚完成编程入门课程的第3周,所以我确定某些格式有点古怪,对此感到抱歉。

我正在尝试定义一个可以包含两个列表的函数:list1list2,并查看list1是否作为list2的子列表,同时还要进行排序考虑在内。

例如,书中的问题是这样的:

如果list1定义为: [15, 1, 100]

list2定义为: [20, 15, 30, 50, 1, 100]

然后list1list2的子列表,因为list1中的数字(15、1和100)以相同的顺序出现在list2 中。

但是,list [15, 50, 20]不是list2的子列表,因为顺序不相同。

我不确定我是否会以正确的方式进行操作,但是我想附上我到目前为止所拥有的内容,并希望有人对此表示赞同。我添加了评论,以便对我的思考过程有更多的了解。



l1 = eval(input('\nPlease enter a list of integers: '))
l2 = eval(input('\nPlease enter a second list of integers: '))

def subList(l1, l2):
    'Takes two lists as input from the user and determines'
    'True if list1 is a sublist of list2 and false otherwise.'

    newLst = []
    indexNum = 0
    result = subList(l1, l2)

    if len(l1) > len(l2):
        return False
    elif l1 == []:
        return True

    for num in l1:

        #My thinking here is that this while loop should run for as long     as ther variable indexNum
        #Doesn't exceed the length of lst2, allowing me to compare every num of lst1 with that of lst2
        while indexNum < len(l2):

            #If I come across a number in lst2, at a certain index, that's the same as lst1 I want
            #to execute the following:
            if l2[indexNum] == num:

                #I've added a blank list at the top, newLst, which I want to append the matching number to.
                newLst.append(l2[indexNum])

                #I'll also want to still add one to the indexNum variable to compare the next number in lst2
                indexNum = indexNum + 1

                break

                #If the number at lst2[indexNum] isn't equal to that of lst1, I still want to add to the
                ##indexNum variable to keep going through the loop and comparing the other items.
            else:
                indexNum = indexNum + 1

        ## I'm thinking here that if at the end of the outer loop, if my newLst is equal to the lst1, then that
        ## should mean that it works as a sub list. I could be wrong here and my thinking is way off though.
        ## If it is equal then the return value should be true, if not false.
        if l1 == newLst:
            return True
        else:
            return False
    return True

2 个答案:

答案 0 :(得分:2)

我继续检查了您的代码。我不得不说,几乎有人似乎在一个完美的解决方案中故意插入了坏行:

  1. 您在函数的第6行有一个递归调用。这不仅没有用,而且会使函数继续递归。
  2. 最后一个if...else也将其杀死。显然newlst不等于l1,因为到您来这里时,您最多只检查了l1的一个元素-删除它。
  3. 这使newlst毫无用处。
  4. 同时使用。不要像在这里那样自然地看到许多好的用法-很好!

我错过了@Olivier的添加内容

  1. 检查l1为空是多余的-循环将跳过,并且您返回True
  2. 在中断之前,您仍然需要增加计数器

这是固定的解决方案:

def subList(l1, l2):
    indexNum = 0
    if len(l1) > len(l2): return False

    for num in l1:
        while indexNum < len(l2):
            if l2[indexNum] == num: 
                indexNum = indexNum + 1
                break
            indexNum = indexNum + 1
        else:
            return False
    return True

l1 = [15,1,100]
l2 = [20,15,30,50,1,100]
l3 = [15,50,20]
print(subList(l1,l2))
print(subList(l3,l2))

循环的逻辑:

  1. l1中取一个项目。
  2. 循环,直到在l2中找到它为止。 indexNum在每次迭代之间都能很好地解决这一问题。
  3. else(如果找不到),返回False
  4. 如果您成功对True中的所有元素执行此操作,请返回l1

您的解决方案不仅简单,而且效率最高。

答案 1 :(得分:0)

您可以通过使用列表理解和内置的all()来检查列表是否相等来解决此问题


l1 = [1,3,4]

l2 = [7,9,1,2,1,3,4,9,8,1,3,4,9]

# the length of the looked for list
lenL1=len(l1)

# create all sublists of this length from each starting position of l2 up to its end
# and check if this sublist has exactly the same digits as the l1 list using all()
a = [(l2[i:i+lenL1],i) for i in range(len(l2)-lenL1) \
                       if all(l1[q]==l2[i+q] for q in range(lenL1))]

print(a)

输出:

[([1, 3, 4], 4), ([1, 3, 4], 9)]

它在l2的第4和第9个帖子中找到了子列表


如果您希望使用“写出”方法而不是列表理解方法,则可以执行类似的操作:

def checker(l1,l2):
    """Enuimerates over l2, finds a value thats same as l1[0] and delegates
    sublistchecking to inner function checkSame"""
    def checkSame(a,b):
        """gets two lists of same length and checks that theire values are identical"""
        return all(a[i] == b[i] for i in range(1,len(a))) # 0 was checked already

    l1_len = len(l1) # store length so we do not need to lookup it all the time

    for idx,value in enumerate(l2):
        if value == l1[0]:          # check 0
            if  checkSame(l1,l2[idx:idx+l1_len]):
                yield(l1,idx) 

print(list(checker(l1,l2)))

如果需要将索引插入值中可迭代的内容中,我更喜欢使用enumerate(iterable)-枚举返回两个值:

Doku enumerate(iterable[,start])