【问题标题】:comparing two lists recrusively递归比较两个列表
【发布时间】:2022-01-08 06:53:55
【问题描述】:

我的教授给了我一个 python 任务来比较 2 个二维列表,如果列表中的所有对象都相似,则返回 True,否则返回 False。 列表的类型为 list[list[int]]。 这必须使用递归来完成。 我不允许使用循环或切片。 (但可以访问列表中的特定索引) 列表的内部划分可能不同,但只要列表中相似位置的所有元素相似,函数就会返回 True。 例如 - [[1], [2, 3, 4]] , [[1, 2], [3, 4]] - 函数将返回 true。 我希望细节清楚,谢谢!

我的问题是找到解决这个问题的方法:)

【问题讨论】:

  • 实际上,这在 Python 中有点无意义,因为 Python 可以将嵌套列表与其== 运算符进行比较... - 你可以开玩笑地写def compare(lol1, lol2): return lol1 == lol2 - 这绝对是一个工作Python 中的解决方案 ;) .
  • 这实际上是一个很棒的python作业!感谢分享。但是你有问题吗?
  • @Gwang-JinKim 我理解问题陈述的方式,你的“解决方案”根本行不通。
  • 哈哈遗憾的是,我们的大多数任务都是毫无意义的,只是为了让我们无缘无故地努力工作......我只能使用 == 来比较列表中的 int 而不是列表本身 :(
  • 我的意思是开玩笑——这种任务通常来自口语。但是对于递归,您必须比较列表的第一个元素(lisp 中的car)和列表的其余部分(cdr)-但问题是-您不允许使用切片...以及如何使用可以在不切片的情况下获取列表的其余部分吗? ...

标签: python list recursion multidimensional-array comparison


【解决方案1】:
a1 = [[1], [2, 3, 4]]
a2 = [[1, 2], [3, 4]]

def get_next_indexes(i, j, a):  # function for getting next indexes based on previous
    return (i + 1, 0)if j >= len(a[i]) - 1 else (i, j + 1)

def compare_lists(i1, j1, i2, j2):  # i1 and j1 - indexes for first array; i2 and j2 - indexes for second array
    if i1 >= len(a1) or i2 >= len(a2):
        print("Two lists are equal.")
        exit(0)
    if a1[i1][j1] != a2[i2][j2]:
        print("Two lists are not equal.")
        exit(0)
    print(get_next_indexes(i1, j1, a1))
    compare_lists(*get_next_indexes(i1, j1, a1), *get_next_indexes(i2, j2, a2))

compare_lists(0, 0, 0, 0)

【讨论】:

    【解决方案2】:

    通常你对列表中的carcdrfirstrest)执行l[0]l[1:]

    这项任务最大的挑战是禁止切片。

    但是有

    first, *rest = your_list 
    

    有效!不仅不用切片,而且不用索引。

    def first(l):        # traditionally in Lisp languages `CAR`
        car, *cdr = l
        return car
        
    def rest(l):         # traditionally in Lisp languages `CDR`
        car, *cdr = l
        return cdr
    
    def comp(lol1, lol2):
        if len(lol1) == len(lol2) == 0:  # recursion end condition
            return True
        # if first elements are lists, `comp`are the firsts and the rests
        elif type(first(lol1)) == type(first(lol2)) == list:
            return comp(first(lol1), first(lol2)) and \
                   comp(rest(lol1), rest(lol2))
        # if first elements are atoms (non-lists), `==` the firsts and `comp`are the rest
        else: # then the firsts are atoms!
            return first(lol1) == first(lol1) and \
                   comp(rest(lol1), rest(lol2))
        
    # traditionally in Lisp languages, you test not for list
    # but for `atom` (whether the first elements of the lists are
    # non-lists -> atomar). But `atom` is not that easy test in Python.
    # so it is must more easy to ask whether both first elements are lists - and 
    # if not - then it is clear that the first elements of non-empty lists must be non-lists => atoms.
    
    
    
     
    

    这适用于 Python3,但不适用于 Python2。

    对于 Python2 和 Python3,您可以使用函数定义:

    def first(l):
        return (lambda x, *y: x)(*l)
    
    def rest(l):
        return (lambda x, *y: y)(*l)
    

    单索引和.pop()

    也许你老师的想法是:

    def first(l):
        return l[0]
        
    def rest(l):
        if l != []:
            l.pop()
            return l
        else:
            return []
    
    # For definition of the `comp()` function see above
    

    但是这个解决方案是有问题的,因为它改变了 输入列表,因为 Python 执行 call-by-reference 而不是 call-by-value。为避免这种情况,必须首先对列表进行深度复制。可以通过切片对列表进行浅拷贝,但不允许切片...

    喜欢:

    q = [1, 2, [3, 4], [5, 6, 7], 8]
    comp(q, q)
    ## True
    # so far so good, but:
    q
    ## []
    

    【讨论】:

      猜你喜欢
      • 2020-01-25
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2021-04-15
      相关资源
      最近更新 更多