8

I define intersection of two lists as follows:

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

For three arguments it would look like:

def intersect(a, b, c):
  return (list(set(a) & set(b) & set(c))

Can I generalize this function for variable number of lists?

The call would look for example like:

>> intersect([1, 2, 2], [2, 3, 2], [2, 5, 2], [2, 7, 2])
[2]

EDIT: Python can only achieve it this way?

intersect([
          [1, 2, 2], [2, 3, 2], [2, 5, 2], [2, 7, 2]
         ])
[2]
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
xralf
  • 3,312
  • 45
  • 129
  • 200

2 Answers2

17

Use the *-list-to-argument operator and instead of your custom function use set.intersection:

>>> lists = [[1, 2, 2], [2, 3, 2], [2, 5, 2], [2, 7, 2]]
>>> list(set.intersection(*map(set, lists)))
[2]

If you want the list-to-set-to-list logic inside a function, you can do it like this:

def intersect(lists):
    return list(set.intersection(*map(set, lists)))

If you prefer intersect() to accept an arbitrary number of arguments instead of a single one, use this instead:

def intersect(*lists):
    return list(set.intersection(*map(set, lists)))
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 3
    You don't actually need to setify every list, only the first one - `set(lists[0]).intersection(*lists)` will do the same thing. Not that this is necessarily a good idea, since it is somewhat less readable, but it might be slightly more efficient for very large numbers of lists. – lvc Jun 02 '12 at 09:50
  • @ThiefMaster Python can only take an argument as a list? can't it take variable number of arguments? – xralf Jun 02 '12 at 09:53
  • 3
    @xralf: If you want `intersect()` to accept multiple arguments, use `def intersect(*lists)`. Then `lists` will be a list containing all positional arguments. – ThiefMaster Jun 02 '12 at 09:56
  • This is not a good solution. It fails when `lists` is empty. – Dirk Groeneveld Nov 29 '21 at 23:59
0
def intersect(*lists):
    if(len(lists) <=1):
        return lists[0]

    result = lists[0]
    for i in range(1, len(lists)):
        result = set(result) & set(lists[i])

    return list(result)

Call the function just like this...

intersect([1,2],[2,3],[2,4])

Leaving all sanitation to you.

Ramesh
  • 406
  • 3
  • 9
  • It is not very pythonic, iterating over a list using the index shouldn't ever need to be used in Python. – jamylak Jun 03 '12 at 01:00