Reputation: 109
I have a list of tuples and lists in python:
gammagammalambda = [[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('r', 'u'), ('p', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('r', 'w'), ('p', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
Where
[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]]
is the same as
[[('r', 'w'), ('p', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]
So now, I want to remove these double elements, in order to have
[[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
For that, I want to use List comprehension and I've tried with
main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in gammagammalambda)
But I get the error:
TypeError: unhashable type: 'list'
Hope, you can help me.
Upvotes: 1
Views: 84
Reputation: 164663
Similar to this answer, list
is not hashable, tuple
and frozenset
are hashable.
You can accordingly define a "uniqueness key", and use the itertools
unique_everseen
recipe, also available in 3rd party libraries as toolz.unique
or more_itertools.unique_everseen
:
from more_itertools import unique_everseen
L = [[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('r', 'u'), ('p', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('r', 'w'), ('p', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
def unique_everseen(x):
return frozenset(x[0]), tuple(map(tuple, x[1][0]))
res = list(unique(L, key=unique_key))
[[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
Upvotes: 0
Reputation: 61910
One alternative is the following:
gammagammalambda = [[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('r', 'u'), ('p', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('r', 'w'), ('p', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
d = {frozenset(e[0]) : e for e in reversed(gammagammalambda)}
result = list(d.values())
print(result)
Output
[[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
Create a dictionary where the keys represent the values that must be unique, for each key set as value the entire element of gammagammalambda
, finally the unique values are the values of the dictionary d
.
Or a more straightforward alternative:
gammagammalambda = [[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('r', 'u'), ('p', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]],
[[('r', 'w'), ('p', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
seen = set()
result = []
for e in gammagammalambda:
key = frozenset(e[0])
if key not in seen:
result.append(e)
seen.add(key)
print(result)
Output
[[[('p', 'u'), ('r', 'w')], [[[], ['q', 's'], ['t', 'v'], []]]], [[('p', 'w'), ('r', 'u')], [[[], ['q', 's'], ['t', 'v'], []]]]]
Upvotes: 3