问题
Using this code:
from itertools import product
list1 = ['Gabe', 'Taylor', 'Kyle', 'Jay']
list2 = ['Gabe', 'Taylor', 'Kyle', 'Jay', 'James', 'John', 'Tyde','Chris', 'Bruno', 'David']
list3 = ['Gabe', 'Taylor', 'Kyle', 'Jay', 'James', 'John', 'Tyde','Chris', 'Bruno', 'David']
list4 = ['Kyle', 'James', 'John', 'Tyde','Bruno', 'Drew', 'Chris']
list5 = ['James', 'John', 'Brendan','Tim', 'Drew' ]
FinalList = []
for x in product(list1, list2, list3, list4, list5):
# check for duplicates
if len(set(x)) == 5:
FinalList.append(x)
# to print
for x in FinalList:
print x
I print out all unique lists. However many of the printed lists are unique only because they are the same elements in a different order.
How can I change my code so that I only print a list if it hasn't already been printed just ordered differently?
回答1:
frozenset
is hashable and does not care about the order of its contents. Simply use a set rather than a list for your final_data
and entries with the same names in different orders will be coalesced into one entry in final_data
:
final_data = set()
for x in product(list1, list2, list3, list4, list5):
datum = frozenset(x)
if len(datum) == 5:
final_data.add(datum)
回答2:
Instead of checking the size of the set, as you do, store each of them, also in a set (it makes lookup simple).
Then check is you already know the set(x)
; if you do, skip it, else put it into the set of known sets.
To store a set in a set, you have to make the inner set immutable, by using frozenset
instead of set
.
Working code:
from itertools import product
list1 = ['Gabe', 'Taylor', 'Kyle', 'Jay']
list2 = ['Gabe', 'Taylor', 'Kyle', 'Jay', 'James', 'John', 'Tyde','Chris', 'Bruno', 'David']
list3 = ['Gabe', 'Taylor', 'Kyle', 'Jay', 'James', 'John', 'Tyde','Chris', 'Bruno', 'David']
list4 = ['Kyle', 'James', 'John', 'Tyde','Bruno', 'Drew', 'Chris']
list5 = ['James', 'John', 'Brendan','Tim', 'Drew' ]
def FindUniques(*lists):
already_seen = set()
result = []
for x in product(*lists):
icicle = frozenset(x)
if icicle not in already_seen:
result.append(x)
already_seen.add(icicle)
return result
final_list = FindUniques(list1, list2, list3, list4, list5)
# make sure that each element in final_list, independent of elemet order, is unique
assert len(final_list) == len(set(tuple(sorted(list(x))) for x in final_list))
# to print
for x in final_list:
print x
来源:https://stackoverflow.com/questions/20234030/keeping-only-unique-instances-of-lists-whose-only-difference-is-order