Hashable Data Structure With No Order And Allowed Duplicates
I have list of tuples/lists (-1, 0, 1) (-1, 1, 0) (-1, 2, -1) (-1, -1, 2) (0, 1, -1) I need them to be : (-1, 1, 0) (-1, 2, -1) I want (-1, 0, 1) and (-1, 1, 0) map to the same thi
Solution 1:
You could sort the tuples and use set
to check for duplicates as tuples are hashable
a=[(-1, 0, 1) ,(-1, 1, 0), (-1, 2, -1) ,(-1, -1, 2), (0, 1, -1)]
my_set=set()
res=[]
for original_value, sorted_value inzip(a,map(sorted,a)):
iftuple(sorted_value) notin my_set:
res.append(original_value)
my_set.add(tuple(sorted_value))
Output
[(-1, 0, 1), (-1, 2, -1)]
Can use defaultdict
from collections import defaultdict
d=defaultdict(list)
a=[(-1, 0, 1) ,(-1, 1, 0), (-1, 2, -1) ,(-1, -1, 2), (0, 1, -1)]
res=[]
for original_value, sorted_value inzip(a,map(sorted,a)):
d[tuple(sorted_value)].append(original_value)
Output:
{
(-1, -1, 2): [(-1, 2, -1), (-1, -1, 2)],
(-1, 0, 1): [(-1, 0, 1), (-1, 1, 0), (0, 1, -1)]
}
Solution 2:
You can use collections.Counter
to efficiently take the signatures of each tuple in your list, map the items of the Counter
objects to frozensets so the signatures become hashable, put them in a set to de-duplicate, and then re-create the tuples using the Counter.elements()
method:
from collections import Counter
l = [(-1, 0, 1), (-1, 1, 0), (-1, 2, -1), (-1, -1, 2), (0, 1, -1)]
[tuple(Counter(dict(i)).elements()) for i in {frozenset(Counter(t).items()) for t in l}]
This returns:
[(0, -1, 1), (-1, -1, 2)]
Solution 3:
You can use set
to avoid adding elements that map to the same thing.
l = [(-1, 0, 1), (-1, 1, 0), (-1, 2, -1), (-1, -1, 2), (0, 1, -1)]
new_l = []
for i in l:
ifset(i) not in [set(j) for j in new_l]:
new_l += [i]
print new_l
It returns [(-1, 0, 1), (-1, 2, -1)]
Edit
This incorrectly flags some tuples as duplicates. This should work :
l = [(-1, 0, 1), (-1, 1, 0), (-1, 2, -1), (-1, -1, 2), (0, 1, -1)]
new_l = list(set([tuple(sorted(i)) for i in l]))
print new_l
Post a Comment for "Hashable Data Structure With No Order And Allowed Duplicates"