Find intersection of two nested lists?

前端 未结 20 1096
星月不相逢
星月不相逢 2020-11-22 04:16

I know how to get an intersection of two flat lists:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

or

<
相关标签:
20条回答
  • 2020-11-22 04:55

    The functional approach:

    input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]
    
    result = reduce(set.intersection, map(set, input_list))
    

    and it can be applied to the more general case of 1+ lists

    0 讨论(0)
  • 2020-11-22 04:58

    I don't know if I am late in answering your question. After reading your question I came up with a function intersect() that can work on both list and nested list. I used recursion to define this function, it is very intuitive. Hope it is what you are looking for:

    def intersect(a, b):
        result=[]
        for i in b:
            if isinstance(i,list):
                result.append(intersect(a,i))
            else:
                if i in a:
                     result.append(i)
        return result
    

    Example:

    >>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
    >>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
    >>> print intersect(c1,c2)
    [[13, 32], [7, 13, 28], [1, 6]]
    
    >>> b1 = [1,2,3,4,5,9,11,15]
    >>> b2 = [4,5,6,7,8]
    >>> print intersect(b1,b2)
    [4, 5]
    
    0 讨论(0)
  • 2020-11-22 04:59

    Do you consider [1,2] to intersect with [1, [2]]? That is, is it only the numbers you care about, or the list structure as well?

    If only the numbers, investigate how to "flatten" the lists, then use the set() method.

    0 讨论(0)
  • 2020-11-22 05:00

    You don't need to define intersection. It's already a first-class part of set.

    >>> b1 = [1,2,3,4,5,9,11,15]
    >>> b2 = [4,5,6,7,8]
    >>> set(b1).intersection(b2)
    set([4, 5])
    
    0 讨论(0)
  • 2020-11-22 05:00

    You should flatten using this code ( taken from http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), the code is untested, but I'm pretty sure it works:

    
    def flatten(x):
        """flatten(sequence) -> list
    
        Returns a single, flat list which contains all elements retrieved
        from the sequence and all recursively contained sub-sequences
        (iterables).
    
        Examples:
        >>> [1, 2, [3,4], (5,6)]
        [1, 2, [3, 4], (5, 6)]
        >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
        [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""
    
        result = []
        for el in x:
            #if isinstance(el, (list, tuple)):
            if hasattr(el, "__iter__") and not isinstance(el, basestring):
                result.extend(flatten(el))
            else:
                result.append(el)
        return result
    

    After you had flattened the list, you perform the intersection in the usual way:

    
    c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
    c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
    
    def intersect(a, b):
         return list(set(a) & set(b))
    
    print intersect(flatten(c1), flatten(c2))
    
    
    0 讨论(0)
  • 2020-11-22 05:00

    I was also looking for a way to do it, and eventually it ended up like this:

    def compareLists(a,b):
        removed = [x for x in a if x not in b]
        added = [x for x in b if x not in a]
        overlap = [x for x in a if x in b]
        return [removed,added,overlap]
    
    0 讨论(0)
提交回复
热议问题