Remove duplicate list tuples from the list
I want to write a script to get the list of categories and return the only way to divide the categories into 2 groups. Now I have its tuple form (list_a, list_b), where the union of list_a and list_b represents the complete list of categories.
Below I show an example of a category [‘A’, ‘B’,’C’,’D’] where I can get all groups. However, some are duplicates ([‘A’], [‘B’, ‘C’, ‘D’]) denote the same as ([‘B’, ‘C’, ‘D’], [‘A’]). Also What is a better title for this article?
import itertools
def getCompliment(smallList, fullList):
compliment = list()
for item in fullList:
if item not in smallList:
compliment.append(item)
return compliment
optionList = ['A','B','C','D']
combos = list()
for r in range(1,len(optionList)):
tuples = list(itertools.combinations(optionList, r))
for t in tuples:
combos.append((list(t),getCompliment(list(t), optionList)))
print(combos)
[(['A'], ['B', 'C', 'D']),
(['B'], ['A', 'C', 'D']),
(['C'], ['A', 'B', 'D']),
(['D'], ['A', 'B', 'C']),
(['A', 'B'], ['C', 'D']),
(['A', 'C'], ['B', 'D']),
(['A', 'D'], ['B', 'C']),
(['B', 'C'], ['A', 'D']),
(['B', 'D'], ['A', 'C']),
(['C', 'D'], ['A', 'B']),
(['A', 'B', 'C'], ['D']),
(['A', 'B', 'D'], ['C']),
(['A', 'C', 'D'], ['B']),
(['B', 'C', 'D'], ['A'])]
I need the following:
[(['A'], ['B', 'C', 'D']),
(['B'], ['A', 'C', 'D']),
(['C'], ['A', 'B', 'D']),
(['D'], ['A', 'B', 'C']),
(['A', 'B'], ['C', 'D']),
(['A', 'C'], ['B', 'D']),
(['A', 'D'], ['B', 'C'])]
Solution
You are very close. What you need is a set of results.
Because the set
element must be hashable and the list
object is non-hashable, you can use tuple
instead. This can be achieved by making some trivial changes to the code.
import itertools
def getCompliment(smallList, fullList):
compliment = list()
for item in fullList:
if item not in smallList:
compliment.append(item)
return tuple(compliment)
optionList = ('A','B','C','D')
combos = set()
for r in range(1,len(optionList)):
tuples = list(itertools.combinations(optionList, r))
for t in tuples:
combos.add(frozenset((tuple(t), getCompliment(tuple(t), optionList))))
print(combos)
{frozenset({('A',), ('B', 'C', 'D')}),
frozenset({('A', 'C', 'D'), ('B',)}),
frozenset({('A', 'B', 'D'), ('C',)}),
frozenset({('A', 'B'), ('C', 'D')}),
frozenset({('A', 'C'), ('B', 'D')}),
frozenset({('A', 'D'), ('B', 'C')}),
frozenset({('A', 'B', 'C'), ('D',)})}
If you need to convert the results back to a list of lists, this can be achieved with list understanding:
res = [list(map(list, i)) for i in combos]
[[['A'], ['B', 'C', 'D']],
[['B'], ['A', 'C', 'D']],
[['A', 'B', 'D'], ['C']],
[['A', 'B'], ['C', 'D']],
[['B', 'D'], ['A', 'C']],
[['B', 'C'], ['A', 'D']],
[['A', 'B', 'C'], ['D']]]