测试二维列表是否与递归相等

Testing if 2d lists are equal with recursion

提问人:Dr.jj 提问时间:12/13/2022 最后编辑:ggorlenDr.jj 更新时间:12/14/2022 访问量:82

问:

我需要制作一个接收 2 个嵌套列表的函数,并检查它们是否与递归相同。主要问题是不允许我在列表中使用运算符、更改原始列表或使用循环。如果列表相同,则该函数返回 True,如果列表不相同,则返回 False。==

例如,该函数将为列表返回 True

lst_1 = [[1,2,3], [4,5,6]] lst_2 = [[1,2,3], [4,5,6]]

并返回 False:

lst_1 = [[1,2,3], [4,5,6]] lst_2 = [[1,2,3], [4,5]]
def func(l1, l2):
    if len(l1) != len(l2):
        return False
    if len(l1[0]) == 0 and len(l2[0]) == 0:
        return True
    if len(l1[-1]) == 0 and len(l2[-1]) == 0:
        del l1[-1]
        del l2[-1]

    if l1[-1][-1] != l2[-1][-1]:
        return False
    l1[-1].pop(-1)
    l2[-1].pop(-1)
    return func(l1, l2)

我曾尝试用流行音乐来做到这一点,但显然它改变了原始列表。

Python 递归 嵌套列表

评论

0赞 John Coleman 12/13/2022
您可以切片而不是弹出
0赞 Dr.jj 12/13/2022
@JohnColeman切片会更改原始列表
0赞 codingStarter 12/13/2022
你能复制列表吗?比如发送 l1[:-1] 作为参数?
0赞 John Coleman 12/13/2022
不,它没有。切片不是突变。问题描述并没有说递归调用中的列表必须是相同的列表,只是说这些列表没有发生突变。如果你不能做一些合理的事情,你总是可以定义一个传递索引的帮助程序函数。
0赞 Dr.jj 12/13/2022
@JohnColeman 不允许我对列表进行任何操作,只能进行 O1(时间补偿)操作,而不能触及原始列表

答:

-1赞 codingStarter 12/13/2022 #1

此函数进行两次递归调用 - 一个深入数组中的当前位置,另一个进入数组中的下一个位置。 这样,递归将涵盖列表的所有元素和每个嵌套列表。

def func(l1, l2, index = 0):
    if(isinstance(l1,int) and isinstance(l2,int)):
        return l1 == l2
    if len(l1) != len(l2):
        return False
    if(isinstance(l1,list) and isinstance(l2,list)):
        if(index >= len(l1)):
            return True
        return func(l1[index],l2[index],0) and func(l1, l2,index +1)    
    return False  

评论

0赞 Dr.jj 12/13/2022
有什么方法可以将其拆分为 2 个函数吗?main 函数只需要获取 2 个列表作为参数
0赞 codingStarter 12/13/2022
它有一个默认参数,因此它只能采用两个参数。例如,调用 func([1],[1]) 将按预期工作
0赞 Dr.jj 12/13/2022
该函数为以下内容返回 True:([[1,2,3], [4,5,6]],[[1,2,3], [4,5,3]]))
0赞 Dr.jj 12/13/2022
没问题!我仍然无法真正理解这里发生了什么,所以如果你能简要解释一下这里发生了什么,那将是惊人的:)
0赞 codingStarter 12/13/2022
如果我的答案是正确的,请将其标记为已接受
0赞 pho 12/14/2022 #2

这是一组愚蠢的限制,但很好!

要使列表列表相等,两个列表中的所有相应元素必须相等。如果这些元素本身就是列表,则相同的逻辑适用于这些列表中的所有元素。

我们可以说,如果两个列表的第一个元素相等,则两个列表相等,并且构成其余元素的列表也相等,而不是遍历列表。

def lists_equal(lst1, lst2):
    # If either argument is not a list, do the == check
    if not isinstance(lst1, list) or not isinstance(lst2, list):
        return lst1 == lst2

    # If both lists are empty, then the lists are equal
    if not lst1 and not lst2:
        return True

    # If either list is empty but both aren't, then the lists aren't equal
    if not lst1 or not lst2:
        return False

    # Both arguments are lists, so all of their elements must be equal
    #                  First elements equal              Remaining elements equal
    #                  vvvvvvvvvvvvvvvv                  vvvvvvvvvvvvvvvvvv
    return lists_equal(lst1[0], lst2[0]) and lists_equal(lst1[1:], lst2[1:])
    

tests = [
          ([[1,2,3], [4,5,6]], [[1,2,3], [4,5,6]], True),
          ([[1,2,3], [4,5,6]], [[1,2,3], [4,5]], False),
          ([[1,[2,3], [4, 5], 6], [4,5,6]], [[1,[2,3], [4, 5], 6], [4,5,6]], True),
          ([[1,[2,3], [4, 5], 6], [4,5,6]], [[1,[2,3], [4, 5], 6], [4,5]], False),
        ]

for lst1, lst2, result in tests:
    assert lists_equal(lst1, lst2) == result