I have a long list of lists in Python that looks something like this:
myList=[
('a',[1,2,3,4,5]),
('b',[6,7,8,9,10]),
('c',[1,3,5,7,9]),
('d',[2,4,6,8,10]),
('e',[4,5,6,7,8])
]
And I would like to enumerate the common values exhaustively
('a:b', ),
('a:c', [1,3,5]),
('a:d', [2,4]),
('a:e', [4,5]),
('b:c', [7,9]),
('b:d', [6,8,10]),
('a:c:e', [5]),
('b:c:e', [7]),
('b:d:e', [6,8]),
and the same for groups of four, five, six until all common values have been identified (assuming the lists were longer)
Is this possible using the itertools
library or sets or a combination of the above?
I have been trying to write a function that loops over the original list for every new list I generate but It hasn't been going well!
Here is what I have:
def findCommonElements(MyList):
def sets(items):
for name, tuple in items:
yield name, set(tuple)
def matches(sets):
for a, b in combinations(sets, 2):
yield ':'.join([a[0], b[0]]), a[1] & b[1]
combinationsSet=list(matches(sets(keywordCount)))
combinationsList=[]
for pair,tup in combinationsSet:
setList=list(tup)
combinationsList.append((pair, len(setList), setList))
combinationsList=sorted(combinationsList,key=lambda x: x[1], reverse=True) #this just sorts the list by the number of common elements
return combinationsList
I think You can try to use itertools.combinations
with itertools.chain
nit very good example but It should work.
I will use itertools
and generators here:
lengthes = xrange(2, len(myList)+1)
combinations_list = (itertools.combinations(myList, i) for i in lengthes)
combinations = itertools.chain.from_iterable(combinations_list)
def find_intersection(lists):
res = set(lists[0])
for data in lists:
res &= set(data)
return res
result = [(':'.join(i), list(find_intersection(v))) for i, v in (zip(*x) for x in combinations)]
or just itertools.combinations
def findCommonElements(MyList):
combinationsList=[]
for seq_len in xrange(2, len(MyList)+1):
for combination in combinations:
for indexes, values in zip(*combination):
intersection = reduce(lambda x, y: x & set(y[1]),
values, set(values[0]))
if intersection:
combinationsList.appen(':'.join(indexes), intersection)
return combinationsList