Find intersection of two nested lists?

前端 未结 20 1042
星月不相逢
星月不相逢 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 05:04

    flat list can be made through reduce easily.

    All you need to use initializer - third argument in the reduce function.

    reduce(
       lambda result, _list: result.append(
           list(set(_list)&set(c1)) 
         ) or result, 
       c2, 
       [])
    

    Above code works for both python2 and python3, but you need to import reduce module as from functools import reduce. Refer below link for details.

    • for python2

    • for python3

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

    For people just looking to find the intersection of two lists, the Asker provided two methods:

    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]
    

    and

    def intersect(a, b):
         return list(set(a) & set(b))
    
    print intersect(b1, b2)
    

    But there is a hybrid method that is more efficient, because you only have to do one conversion between list/set, as opposed to three:

    b1 = [1,2,3,4,5]
    b2 = [3,4,5,6]
    s2 = set(b2)
    b3 = [val for val in b1 if val in s2]
    

    This will run in O(n), whereas his original method involving list comprehension will run in O(n^2)

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

    The & operator takes the intersection of two sets.

    {1, 2, 3} & {2, 3, 4}
    Out[1]: {2, 3}
    
    0 讨论(0)
  • 2020-11-22 05:07

    To define intersection that correctly takes into account the cardinality of the elements use Counter:

    from collections import Counter
    
    >>> c1 = [1, 2, 2, 3, 4, 4, 4]
    >>> c2 = [1, 2, 4, 4, 4, 4, 5]
    >>> list((Counter(c1) & Counter(c2)).elements())
    [1, 2, 4, 4, 4]
    
    0 讨论(0)
  • 2020-11-22 05:08

    Given:

    > 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]]
    

    I find the following code works well and maybe more concise if using set operation:

    > c3 = [list(set(f)&set(c1)) for f in c2] 
    

    It got:

    > [[32, 13], [28, 13, 7], [1, 6]]
    

    If order needed:

    > c3 = [sorted(list(set(f)&set(c1))) for f in c2] 
    

    we got:

    > [[13, 32], [7, 13, 28], [1, 6]]
    

    By the way, for a more python style, this one is fine too:

    > c3 = [ [i for i in set(f) if i in c1] for f in c2]
    
    0 讨论(0)
  • 2020-11-22 05:12

    Pure list comprehension version

    >>> 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]]
    >>> c1set = frozenset(c1)
    

    Flatten variant:

    >>> [n for lst in c2 for n in lst if n in c1set]
    [13, 32, 7, 13, 28, 1, 6]
    

    Nested variant:

    >>> [[n for n in lst if n in c1set] for lst in c2]
    [[13, 32], [7, 13, 28], [1, 6]]
    
    0 讨论(0)
提交回复
热议问题