The naive solution is to loop over every pair, which is slow. However, you can do something along the lines of this:
- Create a dict that will map ints (elements in your nested list) to lists containing the indices of the lists in your master.
- Loop over the master list, and for each sublist, add its index to the spot corresponding to each of its elements in the dict.
- Now, the dict has values consisting of lists in which each two elements are a "pair".
This is what I mean:
>>> mylist = [[15], [14, 15], [19, 20], [13], [3], [65, 19], [19, 20, 31]]
>>>
>>> pairs = dict()
>>>
>>>
>>> from collections import defaultdict
>>>
>>> pairs = defaultdict(list)
>>>
>>> for idx, sub in enumerate(mylist):
... for a in sub:
... pairs[a].append(idx)
...
>>> pairs
defaultdict(<type 'list'>, {65: [5], 3: [4], 13: [3], 14: [1], 15: [0, 1], 19: [2, 5, 6], 20: [2, 6], 31: [6]})
You can disregard the value lists with only 1 element (since that means we don't have a pair). Those with 2+ elements form a variety of pairs. For instance with 19
we have [2, 5, 6]
meaning:
- 2 and 5 are a pair
- 2 and 6 are a pair
- 5 and 6 are a pair
as you have. This approach is linear in the total number of items within your nested lists. If you have a reasonable upper bound on the nested list lengths, then this is O(n) in the size of your master list.
Now for the output:
>>> from itertools import combinations
>>>
>>> for k,v in pairs.iteritems():
... if len(v) > 1:
... for a,b in combinations(v, 2):
... print "Index {} matched with index {} for value {}".format(a, b, k)
...
Index 0 matched with index 1 for value 15
Index 2 matched with index 5 for value 19
Index 2 matched with index 6 for value 19
Index 5 matched with index 6 for value 19
Index 2 matched with index 6 for value 20