Delete Tuples in more dimensional list if same
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 |
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 |
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 Nov 19 '18 at 10:01
Netwave
12.5k22144
12.5k22144
asked Nov 19 '18 at 9:59
Armani42Armani42
547
547
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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
Nov 19 '18 at 11:39
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
Nov 19 '18 at 11:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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
Nov 19 '18 at 14:52
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.
– myrmica
Nov 19 '18 at 18:31
add a comment |
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 |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
Nov 19 '18 at 11:39
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
Nov 19 '18 at 11:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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
Nov 19 '18 at 14:52
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.
– myrmica
Nov 19 '18 at 18:31
add a comment |
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
Nov 19 '18 at 11:39
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
Nov 19 '18 at 11:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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
Nov 19 '18 at 14:52
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.
– myrmica
Nov 19 '18 at 18:31
add a comment |
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 Nov 19 '18 at 13:11
answered Nov 19 '18 at 10:57
myrmicamyrmica
44918
44918
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
Nov 19 '18 at 11:39
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
Nov 19 '18 at 11:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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
Nov 19 '18 at 14:52
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.
– myrmica
Nov 19 '18 at 18:31
add a comment |
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
Nov 19 '18 at 11:39
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
Nov 19 '18 at 11:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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
Nov 19 '18 at 14:52
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.
– myrmica
Nov 19 '18 at 18:31
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
Nov 19 '18 at 11:39
Thank you very much! :) So how did you learn that stuff? Is there some tutorial?
– Armani42
Nov 19 '18 at 11:39
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
Nov 19 '18 at 11:42
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
Nov 19 '18 at 11:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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).
– myrmica
Nov 19 '18 at 14:42
@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
Nov 19 '18 at 14:52
@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
Nov 19 '18 at 14:52
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.– myrmica
Nov 19 '18 at 18:31
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.– myrmica
Nov 19 '18 at 18:31
add a comment |
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 |
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 |
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 Nov 19 '18 at 13:06
answered Nov 19 '18 at 10:57
jppjpp
98.9k2160110
98.9k2160110
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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