1

I have a list of lists of lists. Is there any way that I can get the intersection of these. For eg.:

a=[[[1, 2], [2, 3]], [[1, 2], [3, 4]], [[1, 2], [1, 4], [2, 4]]]

From this how can I get [1,2] as the result, which is the common element of those 3 lists of lists ?

wnnmaw
  • 5,444
  • 3
  • 38
  • 63
Sohn
  • 166
  • 3
  • 13
  • Possible duplicate of [Python - Intersection of two lists](http://stackoverflow.com/questions/642763/python-intersection-of-two-lists) – wnnmaw Jun 06 '16 at 16:58
  • 1
    @wnnmaw -- If I'm reading that other question correctly, this definitely is not a dup of that one ... – mgilson Jun 06 '16 at 17:03
  • its not clear what the actual question is ? 1,2 is present in ALL sublists(you say 3 ... but 3 is all there is ... what if there was a 4th sublist that did not contain 1,2?... is this the intention? – Joran Beasley Jun 06 '16 at 17:03
  • Please lookup the similar question and answer as pointed to by @wnnmaw and if this does not help you - eg. beacuse maybe you are just beginning to learn python and lambda, filter et al. are new to you, come back and update the question with where you are still stuck. – Dilettant Jun 06 '16 at 17:04
  • @mgilson, that question is not an *exact* duplicate, but one can very easily solve this question by reading that question and answer. – wnnmaw Jun 06 '16 at 17:06
  • 1
    Well @wnnmaw A better duplicate could be [Intersection of two nested lists in Python](http://stackoverflow.com/q/29462496) – Bhargav Rao Jun 06 '16 at 17:10
  • @BhargavRao, that is a better dupe. Amusingly, it also has a comment pointing to the dupe I picked – wnnmaw Jun 06 '16 at 17:23
  • @BhargavRao -- Agreed. It's a better dupe, but still only handles intersecting 2 lists instead of an arbitrary number. Admittedly, if you can intersect 2, you can do the rest using a loop... – mgilson Jun 06 '16 at 19:48
  • @mgilson Agree to that, It is a dupe of that along with [Python -Intersection of multiple lists?](http://stackoverflow.com/q/3852780), But anyway your answer is quite perfect to be used as a dupe target for others. Hence it is better to leave the post open. – Bhargav Rao Jun 06 '16 at 20:14

1 Answers1

2

I might do it something like this:

>>> sets = [set(tuple(lst) for lst in sublist) for sublist in a]
>>> sets
[set([(1, 2), (2, 3)]), set([(1, 2), (3, 4)]), set([(1, 2), (2, 4), (1, 4)])]
>>> sets[0].intersection(*sets[1:])
set([(1, 2)])

The first step is to realize that some python data-structures can help. set can find the intersection easily if the items are hashable. list aren't hashable, but tuple are and converting between the two is easy. So the first step is to turn your sublists of lists into a sets of tuple.

That's accomplished by the first line:

sets = [set(tuple(lst) for lst in sublist) for sublist in a]

From here, assuming that you have at least one set in sets, you can just pick off the first one and intersect it with all the rest1. Writing it out slightly more verbosely than above:

first_set = sets[0]
rest_of_sets = sets[1:]
intersection = first_set.intersection(*rest_of_sets)

Now you have an intersection (it's a set that contains tuple). We can easily unravel that back into lists if you want:

list_intersection = [list(item) for item in intersection]

1You can also write it as: intersection = set.intersection(*sets) -- It might even be a tiny bit more efficient...

mgilson
  • 300,191
  • 65
  • 633
  • 696