递归函数-比较2个列表,返回两个列表中都不存在的元素

时间:2018-12-22 21:44:55

标签: 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])
 [4, 5]

如果列表的第一个元素(list [0])相同,我可以进行比较,但是如果元素不在第一个位置,我就难以比较...我已经尝试了很多选择但是我是编程的开端,并不真正知道该怎么做。它必须是递归函数,我不能使用FOR或WHILE。有没有不用remove()就可以做到的任何方法?非常感谢

4 个答案:

答案 0 :(得分:1)

这是一个替代答案。重复该操作的次数较少,但会以不遵守技巧的代价为代价,以遵守练习规则:

def compare(a, b):
    if isinstance(b, list):
        # Let's cheat and change the meaning of the parameters.
        return compare(a, set(b)) + compare(b, set(a))
    else:
        result = []

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

            result.extend(compare(a[1:], b))

        return result

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

答案 1 :(得分:0)

以for循环开头(更容易考虑):

def disjunctive_union(a, b):
    a_filt = [x for x in a if x not in b]
    b_filt = [x for x in b if x not in a]
    return a_filt + b_filt

让我们进行“递归”。一种想法是删除我们已经检查过的元素,并在较小的列表中调用我们的函数。

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

...使用上面定义的recursive_filter

(FWIW,我认为整个事情在使非递归函数递归时是没有意义的。)

答案 2 :(得分:0)

您好,这是另一种解决方案。

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]

答案 3 :(得分:0)

如何?

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