Python 递归函数-比较2个列表,返回不';两者都不存在

Python 递归函数-比较2个列表,返回不';两者都不存在,python,Python,我必须做一个递归函数,比较两个列表并返回它们没有共同点的元素 这就是我到目前为止所做的: def compare(list1, list2): if list2[0] in list1: list1.remove(list2[0]) return compare(list1[1:], list2[1:]) return list1 #Example >>>>compare([2, 3, 4, 5], [2, 3]

我必须做一个递归函数,比较两个列表并返回它们没有共同点的元素

这就是我到目前为止所做的:

def compare(list1, list2):
    if list2[0] in list1:
        list1.remove(list2[0])
        return compare(list1[1:], list2[1:])

    return list1  

#Example 
 >>>>compare([2, 3, 4, 5], [2, 3])
 [4, 5]
我可以比较列表的第一个元素(列表[0])是否相同,但如果元素不在第一个位置,我在如何比较元素上遇到了困难……我尝试了许多选项,但我是编程行乞者,不知道如何做。它必须是一个递归函数,我暂时不能使用。有没有什么方法可以不使用remove()来执行此操作?非常感谢

从for循环开始(更容易思考):

让我们将其设置为“递归”。一个想法是删除我们已经检查过的元素,并在较小的列表中调用我们的函数

def disjunctive_union(a, b):
    if len(a) == 0:
        return b

    first = a[0]
    if first not in b:
        return [first] + disjunctive_union(a[1:], b)

    # These filters can individually be made recursive too
    # (and often are in functional languages!)
    a = [x for x in a if x != first]
    b = [x for x in b if x != first]

    return disjunctive_union(a, b)

编辑:要演示过滤器的递归变量,请执行以下操作:

 a = [x for x in a if x != first]
可替换为:

def recursive_filter(pred, xs):
    x = next(xs)
    if pred(x):
        yield x
    yield from recursive_filter(pred, xs)

a = list(recursive_filter(lambda x: x != first, iter(a)))

编辑2:我想了很多,这里有一个更简单的解决方案:

def disjunctive_union(a, b):
    a_filt = list(recursive_filter(lambda x: x not in b, iter(a)))
    b_filt = list(recursive_filter(lambda x: x not in a, iter(b)))
    return a_filt + b_filt
…使用上面定义的递归过滤器


(FWIW,我认为这整件事在使非递归函数递归方面是一种毫无意义的练习…

嗨,这里还有一个解决方案

def diff(l1,l2):
    result=[]
    if len(l1)==0:
    #return l2, finally it will only contain unique elements (if any)
            return l2
    if l1[0] in l2:
        copy=l1[0]
    #remove all occurances of the common element from both lists
        l1=list(filter(lambda a: a != l1[0], l1))
        l2=list(filter(lambda a: a != copy, l2))
    else:
    #if list1's first element is not in list2 add it to result and pop it
        result.append(l1[0])
        l1.pop(0)
    result+=diff(l1,l2)
    return result

list1=[1,3,2,4,4,5]
list2=[1,2,7]
print(diff(list1,list2))
输出:

[3,4,4,5,7]

这个怎么样:


这里有另一个答案。它有较少的重复,但代价是不遵守演习规则:

def比较(a,b):
如果存在(b,列表):
#让我们作弊并更改参数的含义。
返回比较(a,集合(b))+比较(b,集合(a))
其他:
结果=[]
如果是:
如果a[0]不在b中:
result.append(一个[0])
结果.扩展(比较(a[1:],b))
返回结果

在代码中,在再次调用同一函数之前,您从列表中删除了第一个元素。当您使用递归时,这不是必需的,它以不同的方式处理它。在递归中,通常不就地修改序列,而是将一个子部分传递给内部调用。对于内部调用,该小节是整个序列。

如果第一个列表是
[1,2,3,4,4,4,4,5]
?你期望
[4,4,4,4,5]
还是
[4,5]
?第一个列表[2,3,4,5]秒[2,3],我必须返回[4,5],但我问了一个不同的问题。如果第一个列表中有重复项怎么办?来自流行的堆栈溢出类别:你不应该递归地做的事情。@KellyBaptista当你得到老师给你的版本时,你会发布它吗?我很好奇,想知道他是否找到了一个很好的方法来做这件事。不能真正用于:|我已经尝试过并且->不相交的联合([2,3,4,5],[2,3])->只给了我->[5]@KellyBaptista再试一次--我修正了一个小的拼写错误,以前它被(错误地)称为
不相交的联合
compare([2,3,4,5],[2,3]->给了我[[4,5],[5]]哎呀,我有一个打字错误,如果我比较([2,3,4,5],[2,3])->[4,5],它是有效的,但是如果比较([2,3,4,5],[4,5])->[2,3,4,5]你是对的。我明白了。你可以给函数添加关键字参数吗?我简化了一点。现在有了更多的递归=)您可以通过创建一个单独的辅助函数来消除“脏把戏”(
isinstance
);它基本上看起来像我给出的
过滤器
示例,但是顶层函数不会是递归的,是吗?
def diff(l1,l2):
    result=[]
    if len(l1)==0:
    #return l2, finally it will only contain unique elements (if any)
            return l2
    if l1[0] in l2:
        copy=l1[0]
    #remove all occurances of the common element from both lists
        l1=list(filter(lambda a: a != l1[0], l1))
        l2=list(filter(lambda a: a != copy, l2))
    else:
    #if list1's first element is not in list2 add it to result and pop it
        result.append(l1[0])
        l1.pop(0)
    result+=diff(l1,l2)
    return result

list1=[1,3,2,4,4,5]
list2=[1,2,7]
print(diff(list1,list2))
def compare(a, b, original_a = None, original_b = None):
    result = []

    if original_a is None:
        original_a = a
    if original_b is None:
        original_b = b

    if a and a[0] not in original_b:
        result.append(a[0])

    if b and b[0] not in original_a:
        result.append(b[0])

    if a or b:
        result += compare(a[1:], b[1:], original_a, original_b)

    return result