Delete Tuples in more dimensional list if same
up vote
2
down vote
favorite
I have a list of tuples namely:
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]], [[('p', 'u'), ('r', 'w')], [('v', 'q')]], [[('p', 'u'), ('r', 'w')], [('t', 's')]], [[('p', 'u'), ('r', 'w')], [('v', 's')]], [[('p', 'w'), ('r', 'u')], [('t', 'q')]], [[('p', 'w'), ('r', 'u')], [('v', 'q')]], [[('p', 'w'), ('r', 'u')], [('t', 's')]], [[('p', 'w'), ('r', 'u')], [('v', 's')]], [[('r', 'u'), ('p', 'w')], [('t', 'q')]], [[('r', 'u'), ('p', 'w')], [('v', 'q')]], [[('r', 'u'), ('p', 'w')], [('t', 's')]], [[('r', 'u'), ('p', 'w')], [('v', 's')]], **[[('r', 'w'), ('p', 'u')], [('t', 'q')]]**, [[('r', 'w'), ('p', 'u')], [('v', 'q')]], [[('r', 'w'), ('p', 'u')], [('t', 's')]], [[('r', 'w'), ('p', 'u')], [('v', 's')]]]
But now for example the element [[('p','u'),('r','w')], [('t','q')]]
is the same as [[('r','w'),('p','u')], [('t','q')]]
, which are marked fat in the list.
So in the list I have 16 elements, where every element is double.
Now, I want to delete the duplicates, that I have only the first eight elements left.
So naively, I've tried with
[[list(y) for y in set([tuple(set(x)) for x in doublegammas1])]]
But here, he says:
TypeError: unhashable type: 'list'
So my question:
How can I extend the list comprehension, that it works for a more dimensional list?
python tuples double list-comprehension
add a comment |
up vote
2
down vote
favorite
I have a list of tuples namely:
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]], [[('p', 'u'), ('r', 'w')], [('v', 'q')]], [[('p', 'u'), ('r', 'w')], [('t', 's')]], [[('p', 'u'), ('r', 'w')], [('v', 's')]], [[('p', 'w'), ('r', 'u')], [('t', 'q')]], [[('p', 'w'), ('r', 'u')], [('v', 'q')]], [[('p', 'w'), ('r', 'u')], [('t', 's')]], [[('p', 'w'), ('r', 'u')], [('v', 's')]], [[('r', 'u'), ('p', 'w')], [('t', 'q')]], [[('r', 'u'), ('p', 'w')], [('v', 'q')]], [[('r', 'u'), ('p', 'w')], [('t', 's')]], [[('r', 'u'), ('p', 'w')], [('v', 's')]], **[[('r', 'w'), ('p', 'u')], [('t', 'q')]]**, [[('r', 'w'), ('p', 'u')], [('v', 'q')]], [[('r', 'w'), ('p', 'u')], [('t', 's')]], [[('r', 'w'), ('p', 'u')], [('v', 's')]]]
But now for example the element [[('p','u'),('r','w')], [('t','q')]]
is the same as [[('r','w'),('p','u')], [('t','q')]]
, which are marked fat in the list.
So in the list I have 16 elements, where every element is double.
Now, I want to delete the duplicates, that I have only the first eight elements left.
So naively, I've tried with
[[list(y) for y in set([tuple(set(x)) for x in doublegammas1])]]
But here, he says:
TypeError: unhashable type: 'list'
So my question:
How can I extend the list comprehension, that it works for a more dimensional list?
python tuples double list-comprehension
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I have a list of tuples namely:
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]], [[('p', 'u'), ('r', 'w')], [('v', 'q')]], [[('p', 'u'), ('r', 'w')], [('t', 's')]], [[('p', 'u'), ('r', 'w')], [('v', 's')]], [[('p', 'w'), ('r', 'u')], [('t', 'q')]], [[('p', 'w'), ('r', 'u')], [('v', 'q')]], [[('p', 'w'), ('r', 'u')], [('t', 's')]], [[('p', 'w'), ('r', 'u')], [('v', 's')]], [[('r', 'u'), ('p', 'w')], [('t', 'q')]], [[('r', 'u'), ('p', 'w')], [('v', 'q')]], [[('r', 'u'), ('p', 'w')], [('t', 's')]], [[('r', 'u'), ('p', 'w')], [('v', 's')]], **[[('r', 'w'), ('p', 'u')], [('t', 'q')]]**, [[('r', 'w'), ('p', 'u')], [('v', 'q')]], [[('r', 'w'), ('p', 'u')], [('t', 's')]], [[('r', 'w'), ('p', 'u')], [('v', 's')]]]
But now for example the element [[('p','u'),('r','w')], [('t','q')]]
is the same as [[('r','w'),('p','u')], [('t','q')]]
, which are marked fat in the list.
So in the list I have 16 elements, where every element is double.
Now, I want to delete the duplicates, that I have only the first eight elements left.
So naively, I've tried with
[[list(y) for y in set([tuple(set(x)) for x in doublegammas1])]]
But here, he says:
TypeError: unhashable type: 'list'
So my question:
How can I extend the list comprehension, that it works for a more dimensional list?
python tuples double list-comprehension
I have a list of tuples namely:
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]], [[('p', 'u'), ('r', 'w')], [('v', 'q')]], [[('p', 'u'), ('r', 'w')], [('t', 's')]], [[('p', 'u'), ('r', 'w')], [('v', 's')]], [[('p', 'w'), ('r', 'u')], [('t', 'q')]], [[('p', 'w'), ('r', 'u')], [('v', 'q')]], [[('p', 'w'), ('r', 'u')], [('t', 's')]], [[('p', 'w'), ('r', 'u')], [('v', 's')]], [[('r', 'u'), ('p', 'w')], [('t', 'q')]], [[('r', 'u'), ('p', 'w')], [('v', 'q')]], [[('r', 'u'), ('p', 'w')], [('t', 's')]], [[('r', 'u'), ('p', 'w')], [('v', 's')]], **[[('r', 'w'), ('p', 'u')], [('t', 'q')]]**, [[('r', 'w'), ('p', 'u')], [('v', 'q')]], [[('r', 'w'), ('p', 'u')], [('t', 's')]], [[('r', 'w'), ('p', 'u')], [('v', 's')]]]
But now for example the element [[('p','u'),('r','w')], [('t','q')]]
is the same as [[('r','w'),('p','u')], [('t','q')]]
, which are marked fat in the list.
So in the list I have 16 elements, where every element is double.
Now, I want to delete the duplicates, that I have only the first eight elements left.
So naively, I've tried with
[[list(y) for y in set([tuple(set(x)) for x in doublegammas1])]]
But here, he says:
TypeError: unhashable type: 'list'
So my question:
How can I extend the list comprehension, that it works for a more dimensional list?
python tuples double list-comprehension
python tuples double list-comprehension
edited yesterday
Netwave
11.5k21942
11.5k21942
asked yesterday
Armani42
234
234
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
A mutable object (such as a list or a set) cannot be a member of a set. You can use a frozenset, which is immutable.
main_list = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in main_list)
from pprint import pprint
pprint(main_set)
Output:
{(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')}))}
To convert back to the original structure of nested lists:
new_list = [[list(frozen) for frozen in subtuple] for subtuple in main_set]
pprint(new_list)
Output:
[[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('p', 'u'), ('r', 'w')], [('t', 'q')]]]
UPDATE:
A solution that removes the duplicate items in-place from the input data.
unique =
for item in main_list[:]:
frozen_item = frozenset(frozenset(innermost_list) for innermost_list in item)
if frozen_item not in unique:
unique.append(frozen_item)
else:
main_list.remove(item)
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again innew_list
.
– jpp
yesterday
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@7t7Studios, Why not useset
? i.e.unique = set()
andunique.add(frozen_item)
. This, by the way, then becomes identical tounique_everseen
in my solution.
– jpp
22 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias forseen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.
– 7t7 Studios
19 hours ago
add a comment |
up vote
2
down vote
Lists aren't hashable, tuples are hashable. You then need to take a set
of these tuples. But inside these tuples, you want to disregard order. But a tuples of sets are not hashable, so instead you need to use tuples of frozenset
objects:
uniques = {tuple(map(frozenset, i)) for i in doublegammas1}
print(uniques)
{(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 's')}))}
You can then apply this via 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
def uniquekey(x):
return tuple(map(frozenset, x))
res = list(unique_everseen(doublegammas1, key=uniquekey))
print(res)
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]]]
Input data
# input data
doublegammas1 = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
A mutable object (such as a list or a set) cannot be a member of a set. You can use a frozenset, which is immutable.
main_list = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in main_list)
from pprint import pprint
pprint(main_set)
Output:
{(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')}))}
To convert back to the original structure of nested lists:
new_list = [[list(frozen) for frozen in subtuple] for subtuple in main_set]
pprint(new_list)
Output:
[[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('p', 'u'), ('r', 'w')], [('t', 'q')]]]
UPDATE:
A solution that removes the duplicate items in-place from the input data.
unique =
for item in main_list[:]:
frozen_item = frozenset(frozenset(innermost_list) for innermost_list in item)
if frozen_item not in unique:
unique.append(frozen_item)
else:
main_list.remove(item)
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again innew_list
.
– jpp
yesterday
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@7t7Studios, Why not useset
? i.e.unique = set()
andunique.add(frozen_item)
. This, by the way, then becomes identical tounique_everseen
in my solution.
– jpp
22 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias forseen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.
– 7t7 Studios
19 hours ago
add a comment |
up vote
1
down vote
accepted
A mutable object (such as a list or a set) cannot be a member of a set. You can use a frozenset, which is immutable.
main_list = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in main_list)
from pprint import pprint
pprint(main_set)
Output:
{(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')}))}
To convert back to the original structure of nested lists:
new_list = [[list(frozen) for frozen in subtuple] for subtuple in main_set]
pprint(new_list)
Output:
[[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('p', 'u'), ('r', 'w')], [('t', 'q')]]]
UPDATE:
A solution that removes the duplicate items in-place from the input data.
unique =
for item in main_list[:]:
frozen_item = frozenset(frozenset(innermost_list) for innermost_list in item)
if frozen_item not in unique:
unique.append(frozen_item)
else:
main_list.remove(item)
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again innew_list
.
– jpp
yesterday
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@7t7Studios, Why not useset
? i.e.unique = set()
andunique.add(frozen_item)
. This, by the way, then becomes identical tounique_everseen
in my solution.
– jpp
22 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias forseen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.
– 7t7 Studios
19 hours ago
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
A mutable object (such as a list or a set) cannot be a member of a set. You can use a frozenset, which is immutable.
main_list = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in main_list)
from pprint import pprint
pprint(main_set)
Output:
{(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')}))}
To convert back to the original structure of nested lists:
new_list = [[list(frozen) for frozen in subtuple] for subtuple in main_set]
pprint(new_list)
Output:
[[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('p', 'u'), ('r', 'w')], [('t', 'q')]]]
UPDATE:
A solution that removes the duplicate items in-place from the input data.
unique =
for item in main_list[:]:
frozen_item = frozenset(frozenset(innermost_list) for innermost_list in item)
if frozen_item not in unique:
unique.append(frozen_item)
else:
main_list.remove(item)
A mutable object (such as a list or a set) cannot be a member of a set. You can use a frozenset, which is immutable.
main_list = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in main_list)
from pprint import pprint
pprint(main_set)
Output:
{(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')}))}
To convert back to the original structure of nested lists:
new_list = [[list(frozen) for frozen in subtuple] for subtuple in main_set]
pprint(new_list)
Output:
[[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('p', 'u'), ('r', 'w')], [('t', 'q')]]]
UPDATE:
A solution that removes the duplicate items in-place from the input data.
unique =
for item in main_list[:]:
frozen_item = frozenset(frozenset(innermost_list) for innermost_list in item)
if frozen_item not in unique:
unique.append(frozen_item)
else:
main_list.remove(item)
edited yesterday
answered yesterday
7t7 Studios
1917
1917
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again innew_list
.
– jpp
yesterday
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@7t7Studios, Why not useset
? i.e.unique = set()
andunique.add(frozen_item)
. This, by the way, then becomes identical tounique_everseen
in my solution.
– jpp
22 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias forseen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.
– 7t7 Studios
19 hours ago
add a comment |
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again innew_list
.
– jpp
yesterday
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@7t7Studios, Why not useset
? i.e.unique = set()
andunique.add(frozen_item)
. This, by the way, then becomes identical tounique_everseen
in my solution.
– jpp
22 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias forseen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.
– 7t7 Studios
19 hours ago
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again in
new_list
.– jpp
yesterday
The advantage of this solution is it only uses 2 lines. The disadvantage is you are repeating logic (how the list is constructed) by the fact you unravel it via hashing, then put it back together again in
new_list
.– jpp
yesterday
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@jpp I added an in-place solution that seems to work (more as an exercise though, since the original question asked for comprehension rather than loop).
– 7t7 Studios
23 hours ago
@7t7Studios, Why not use
set
? i.e. unique = set()
and unique.add(frozen_item)
. This, by the way, then becomes identical to unique_everseen
in my solution.– jpp
22 hours ago
@7t7Studios, Why not use
set
? i.e. unique = set()
and unique.add(frozen_item)
. This, by the way, then becomes identical to unique_everseen
in my solution.– jpp
22 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias for
seen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.– 7t7 Studios
19 hours ago
Yes, it's basically the same, apart from having to import a 3rd party module. Btw do you know why they make an alias for
seen.add()
? Is it faster that way? Anyway, thanks for linking the libraries, there's lot of interesting stuff there.– 7t7 Studios
19 hours ago
add a comment |
up vote
2
down vote
Lists aren't hashable, tuples are hashable. You then need to take a set
of these tuples. But inside these tuples, you want to disregard order. But a tuples of sets are not hashable, so instead you need to use tuples of frozenset
objects:
uniques = {tuple(map(frozenset, i)) for i in doublegammas1}
print(uniques)
{(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 's')}))}
You can then apply this via 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
def uniquekey(x):
return tuple(map(frozenset, x))
res = list(unique_everseen(doublegammas1, key=uniquekey))
print(res)
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]]]
Input data
# input data
doublegammas1 = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
add a comment |
up vote
2
down vote
Lists aren't hashable, tuples are hashable. You then need to take a set
of these tuples. But inside these tuples, you want to disregard order. But a tuples of sets are not hashable, so instead you need to use tuples of frozenset
objects:
uniques = {tuple(map(frozenset, i)) for i in doublegammas1}
print(uniques)
{(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 's')}))}
You can then apply this via 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
def uniquekey(x):
return tuple(map(frozenset, x))
res = list(unique_everseen(doublegammas1, key=uniquekey))
print(res)
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]]]
Input data
# input data
doublegammas1 = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
add a comment |
up vote
2
down vote
up vote
2
down vote
Lists aren't hashable, tuples are hashable. You then need to take a set
of these tuples. But inside these tuples, you want to disregard order. But a tuples of sets are not hashable, so instead you need to use tuples of frozenset
objects:
uniques = {tuple(map(frozenset, i)) for i in doublegammas1}
print(uniques)
{(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 's')}))}
You can then apply this via 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
def uniquekey(x):
return tuple(map(frozenset, x))
res = list(unique_everseen(doublegammas1, key=uniquekey))
print(res)
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]]]
Input data
# input data
doublegammas1 = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
Lists aren't hashable, tuples are hashable. You then need to take a set
of these tuples. But inside these tuples, you want to disregard order. But a tuples of sets are not hashable, so instead you need to use tuples of frozenset
objects:
uniques = {tuple(map(frozenset, i)) for i in doublegammas1}
print(uniques)
{(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 'q')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
(frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 's')}))}
You can then apply this via 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
def uniquekey(x):
return tuple(map(frozenset, x))
res = list(unique_everseen(doublegammas1, key=uniquekey))
print(res)
[[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]]]
Input data
# input data
doublegammas1 = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
[[('p', 'u'), ('r', 'w')], [('v', 'q')]],
[[('p', 'u'), ('r', 'w')], [('t', 's')]],
[[('p', 'u'), ('r', 'w')], [('v', 's')]],
[[('p', 'w'), ('r', 'u')], [('t', 'q')]],
[[('p', 'w'), ('r', 'u')], [('v', 'q')]],
[[('p', 'w'), ('r', 'u')], [('t', 's')]],
[[('p', 'w'), ('r', 'u')], [('v', 's')]],
[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
[[('r', 'u'), ('p', 'w')], [('v', 'q')]],
[[('r', 'u'), ('p', 'w')], [('t', 's')]],
[[('r', 'u'), ('p', 'w')], [('v', 's')]],
[[('r', 'w'), ('p', 'u')], [('t', 'q')]],
[[('r', 'w'), ('p', 'u')], [('v', 'q')]],
[[('r', 'w'), ('p', 'u')], [('t', 's')]],
[[('r', 'w'), ('p', 'u')], [('v', 's')]]]
edited yesterday
answered yesterday
jpp
82.2k194796
82.2k194796
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372179%2fdelete-tuples-in-more-dimensional-list-if-same%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown