Armani42
Armani42

Reputation: 109

Delete duplicate tuples and lists in list

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

Answers (2)

jpp
jpp

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

Dani Mesejo
Dani Mesejo

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

Related Questions