2

I was wodnering if there was any way to find the common elements of three lists, whilst ignoring a list that is empty among the three. For example I know that:

a = ['a', 'b', 'c', 'd']
b = ['a', 'v', 'd', 'g']
v = ['d']
>>> set(a).intersection(b, v)
    {'d'}

but I was wondering if there was a way to do this:

a = ['a', 'b', 'c', 'd']
b = ['a', 'v', 'd', 'g']
v = []
>>> comparison_method(a, b, v)
    {'a', 'd'}

Or if 2 out of 3 lists were empty, it would just return the list that wasn't.

O.V
  • 23
  • 5
  • Couldn't you just do the intersection on the non-empty lists? – Patrick Yu Nov 27 '15 at 04:11
  • For the function I'm writing I wouldn't know which lists are empty/non-empty. The other option is to go about writing the function differntly, or going throuhg each list and checking which is empty and which is not, and then comparing the ones that are (if there are any). I wanted to check to see if I could do it this way before pursuing that route. – O.V Nov 27 '15 at 04:16

3 Answers3

5

Using filter and then set intersection:

set.intersection(*map(set,filter(None, [a,[],[]])))

O/P: set(['a', 'c', 'b', 'd'])

set.intersection(*map(set,filter(None, [a,b,[]])))

O/P: set(['a', 'd'])

set.intersection(*map(set,filter(None, [a,b,v])))

O/P : set(['d'])

As jme suggested which is a more better solution

set.intersection(*(set(x) for x in [a, b, v] if x))
Community
  • 1
  • 1
Akshay Hazari
  • 3,186
  • 4
  • 48
  • 84
  • 2
    I find `set.intersection(*(set(x) for x in [a, b, v] if x))` to be more readable, but to each his own. BTW, `lambda x:x` is unnecessary here, and can be replaced by `None`. – jme Nov 27 '15 at 04:51
  • @jme Yes It could be changed to None instead. And the list comprehension would work too. I thought of adding a list comprehension answer there earlier as well but kind of got caught up with something. – Akshay Hazari Nov 27 '15 at 04:59
2

Just filter out all the list that have len (i.e. length is not zero) and use set-intersection-

>>>a = ['a', 'b', 'c', 'd']
>>>b = ['a', 'v', 'd', 'g']
>>>v=[]
>>>input_list = [a,v,b]
>>>result = reduce(set.intersection,map(set,filter(len,input_list)))
>>>set(['a', 'd'])
Learner
  • 5,192
  • 1
  • 24
  • 36
1

Sure, very similar to this, but just filter out the empty lists before running the intersection test:

def comparison_method(*args):
    sets = [set(arg) for arg in args if arg]
    if not sets:
        return []
    result = sets[0]
    for s in sets[1:]:
        result = result.intersection(s)
    return result

a = ['a', 'b', 'c', 'd']
b = ['a', 'v', 'd', 'g']
v = []
>>> comparison_method(a, b, v)
    {'a', 'd'}
Community
  • 1
  • 1
lemonhead
  • 5,328
  • 1
  • 13
  • 25