Python: Symmetrical Difference Between List of Sets of Strings
I have a list that contains multiple sets of strings, and I would like to find the symmetric difference between each string and the other strings in the set.
For example, I have the following list:
targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]
For the above, desired output is:
[2, 0, 1]
because in the first set, A and B are not found in any of the other sets, for the second set, there are no unique elements to the set, and for the third set, F is not found in any of the other sets.
I thought about approaching this backwards; finding the intersection of each set and subtracting the length of the intersection from the length of the list, but set.intersection(*) does not appear to work on strings, so I'm stuck:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
>>> set.intersection(*targets)
set()
python-3.x set set-intersection symmetric-difference
add a comment |
I have a list that contains multiple sets of strings, and I would like to find the symmetric difference between each string and the other strings in the set.
For example, I have the following list:
targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]
For the above, desired output is:
[2, 0, 1]
because in the first set, A and B are not found in any of the other sets, for the second set, there are no unique elements to the set, and for the third set, F is not found in any of the other sets.
I thought about approaching this backwards; finding the intersection of each set and subtracting the length of the intersection from the length of the list, but set.intersection(*) does not appear to work on strings, so I'm stuck:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
>>> set.intersection(*targets)
set()
python-3.x set set-intersection symmetric-difference
Is each string a single character? If not, are you going by whether the entire string occurs elsewhere, or just the character by character differences?
– Unsolved Cypher
Nov 20 '18 at 1:00
1
Each string contains at least six characters, and I would like to test the entire occurrence of the string. Perhaps I oversimplified my example, but I wasn't sure that would make a difference.
– SummerEla
Nov 20 '18 at 1:08
add a comment |
I have a list that contains multiple sets of strings, and I would like to find the symmetric difference between each string and the other strings in the set.
For example, I have the following list:
targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]
For the above, desired output is:
[2, 0, 1]
because in the first set, A and B are not found in any of the other sets, for the second set, there are no unique elements to the set, and for the third set, F is not found in any of the other sets.
I thought about approaching this backwards; finding the intersection of each set and subtracting the length of the intersection from the length of the list, but set.intersection(*) does not appear to work on strings, so I'm stuck:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
>>> set.intersection(*targets)
set()
python-3.x set set-intersection symmetric-difference
I have a list that contains multiple sets of strings, and I would like to find the symmetric difference between each string and the other strings in the set.
For example, I have the following list:
targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]
For the above, desired output is:
[2, 0, 1]
because in the first set, A and B are not found in any of the other sets, for the second set, there are no unique elements to the set, and for the third set, F is not found in any of the other sets.
I thought about approaching this backwards; finding the intersection of each set and subtracting the length of the intersection from the length of the list, but set.intersection(*) does not appear to work on strings, so I'm stuck:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
>>> set.intersection(*targets)
set()
python-3.x set set-intersection symmetric-difference
python-3.x set set-intersection symmetric-difference
asked Nov 20 '18 at 0:49


SummerElaSummerEla
782922
782922
Is each string a single character? If not, are you going by whether the entire string occurs elsewhere, or just the character by character differences?
– Unsolved Cypher
Nov 20 '18 at 1:00
1
Each string contains at least six characters, and I would like to test the entire occurrence of the string. Perhaps I oversimplified my example, but I wasn't sure that would make a difference.
– SummerEla
Nov 20 '18 at 1:08
add a comment |
Is each string a single character? If not, are you going by whether the entire string occurs elsewhere, or just the character by character differences?
– Unsolved Cypher
Nov 20 '18 at 1:00
1
Each string contains at least six characters, and I would like to test the entire occurrence of the string. Perhaps I oversimplified my example, but I wasn't sure that would make a difference.
– SummerEla
Nov 20 '18 at 1:08
Is each string a single character? If not, are you going by whether the entire string occurs elsewhere, or just the character by character differences?
– Unsolved Cypher
Nov 20 '18 at 1:00
Is each string a single character? If not, are you going by whether the entire string occurs elsewhere, or just the character by character differences?
– Unsolved Cypher
Nov 20 '18 at 1:00
1
1
Each string contains at least six characters, and I would like to test the entire occurrence of the string. Perhaps I oversimplified my example, but I wasn't sure that would make a difference.
– SummerEla
Nov 20 '18 at 1:08
Each string contains at least six characters, and I would like to test the entire occurrence of the string. Perhaps I oversimplified my example, but I wasn't sure that would make a difference.
– SummerEla
Nov 20 '18 at 1:08
add a comment |
3 Answers
3
active
oldest
votes
The issue you're having is that there are no strings shared by all three sets, so your intersection
comes up empty. That's not a string issue, it would work the same with numbers or anything else you can put in a set.
The only way I see to do a global calculation over all the sets, then use that to find the number of unique values in each one is to first count all the values (using collections.Counter
), then for each set, count the number of values that showed up only once in the global count.
from collections import Counter
def unique_count(sets):
count = Counter()
for s in sets:
count.update(s)
return [sum(count[x] == 1 for x in s) for s in sets]
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
add a comment |
Try something like below:
Get symmetric difference with every set. Then intersect with the given input set.
def symVal(index,targets):
bseSet = targets[index]
symSet = bseSet
for j in range(len(targets)):
if index != j:
symSet = symSet ^ targets[j]
print(len(symSet & bseSet))
for i in range(len(targets)):
symVal(i,targets)
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
add a comment |
Your code example doesn't work because it's finding the intersection between all of the sets, which is 0 (since no element occurs everywhere). You want to find the difference between each set and the union of all other sets. For example:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
result =
for set_element in targets:
result.append(len(set_element.difference(set.union(*[x for x in targets if x is not set_element]))))
print(result)
(note that the [x for x in targets if x != set_element]
is just the set of all other sets)
1
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
1
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the!=
to anis not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)
– Unsolved Cypher
Dec 18 '18 at 23:43
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%2f53384697%2fpython-symmetrical-difference-between-list-of-sets-of-strings%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The issue you're having is that there are no strings shared by all three sets, so your intersection
comes up empty. That's not a string issue, it would work the same with numbers or anything else you can put in a set.
The only way I see to do a global calculation over all the sets, then use that to find the number of unique values in each one is to first count all the values (using collections.Counter
), then for each set, count the number of values that showed up only once in the global count.
from collections import Counter
def unique_count(sets):
count = Counter()
for s in sets:
count.update(s)
return [sum(count[x] == 1 for x in s) for s in sets]
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
add a comment |
The issue you're having is that there are no strings shared by all three sets, so your intersection
comes up empty. That's not a string issue, it would work the same with numbers or anything else you can put in a set.
The only way I see to do a global calculation over all the sets, then use that to find the number of unique values in each one is to first count all the values (using collections.Counter
), then for each set, count the number of values that showed up only once in the global count.
from collections import Counter
def unique_count(sets):
count = Counter()
for s in sets:
count.update(s)
return [sum(count[x] == 1 for x in s) for s in sets]
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
add a comment |
The issue you're having is that there are no strings shared by all three sets, so your intersection
comes up empty. That's not a string issue, it would work the same with numbers or anything else you can put in a set.
The only way I see to do a global calculation over all the sets, then use that to find the number of unique values in each one is to first count all the values (using collections.Counter
), then for each set, count the number of values that showed up only once in the global count.
from collections import Counter
def unique_count(sets):
count = Counter()
for s in sets:
count.update(s)
return [sum(count[x] == 1 for x in s) for s in sets]
The issue you're having is that there are no strings shared by all three sets, so your intersection
comes up empty. That's not a string issue, it would work the same with numbers or anything else you can put in a set.
The only way I see to do a global calculation over all the sets, then use that to find the number of unique values in each one is to first count all the values (using collections.Counter
), then for each set, count the number of values that showed up only once in the global count.
from collections import Counter
def unique_count(sets):
count = Counter()
for s in sets:
count.update(s)
return [sum(count[x] == 1 for x in s) for s in sets]
answered Nov 20 '18 at 1:34
BlckknghtBlckknght
62.4k556100
62.4k556100
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
add a comment |
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
I've found that this answer still works even when there is no difference between sets. @Unsolved Cypher's did not :(
– SummerEla
Dec 18 '18 at 20:56
add a comment |
Try something like below:
Get symmetric difference with every set. Then intersect with the given input set.
def symVal(index,targets):
bseSet = targets[index]
symSet = bseSet
for j in range(len(targets)):
if index != j:
symSet = symSet ^ targets[j]
print(len(symSet & bseSet))
for i in range(len(targets)):
symVal(i,targets)
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
add a comment |
Try something like below:
Get symmetric difference with every set. Then intersect with the given input set.
def symVal(index,targets):
bseSet = targets[index]
symSet = bseSet
for j in range(len(targets)):
if index != j:
symSet = symSet ^ targets[j]
print(len(symSet & bseSet))
for i in range(len(targets)):
symVal(i,targets)
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
add a comment |
Try something like below:
Get symmetric difference with every set. Then intersect with the given input set.
def symVal(index,targets):
bseSet = targets[index]
symSet = bseSet
for j in range(len(targets)):
if index != j:
symSet = symSet ^ targets[j]
print(len(symSet & bseSet))
for i in range(len(targets)):
symVal(i,targets)
Try something like below:
Get symmetric difference with every set. Then intersect with the given input set.
def symVal(index,targets):
bseSet = targets[index]
symSet = bseSet
for j in range(len(targets)):
if index != j:
symSet = symSet ^ targets[j]
print(len(symSet & bseSet))
for i in range(len(targets)):
symVal(i,targets)
answered Nov 20 '18 at 1:29


NaiduNaidu
4,9593817
4,9593817
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
add a comment |
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
I'm pretty sure this calculation will get the wrong answer if any values are in all three sets (or appear any odd number of times if there are more sets than that).
– Blckknght
Dec 18 '18 at 21:15
add a comment |
Your code example doesn't work because it's finding the intersection between all of the sets, which is 0 (since no element occurs everywhere). You want to find the difference between each set and the union of all other sets. For example:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
result =
for set_element in targets:
result.append(len(set_element.difference(set.union(*[x for x in targets if x is not set_element]))))
print(result)
(note that the [x for x in targets if x != set_element]
is just the set of all other sets)
1
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
1
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the!=
to anis not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)
– Unsolved Cypher
Dec 18 '18 at 23:43
add a comment |
Your code example doesn't work because it's finding the intersection between all of the sets, which is 0 (since no element occurs everywhere). You want to find the difference between each set and the union of all other sets. For example:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
result =
for set_element in targets:
result.append(len(set_element.difference(set.union(*[x for x in targets if x is not set_element]))))
print(result)
(note that the [x for x in targets if x != set_element]
is just the set of all other sets)
1
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
1
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the!=
to anis not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)
– Unsolved Cypher
Dec 18 '18 at 23:43
add a comment |
Your code example doesn't work because it's finding the intersection between all of the sets, which is 0 (since no element occurs everywhere). You want to find the difference between each set and the union of all other sets. For example:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
result =
for set_element in targets:
result.append(len(set_element.difference(set.union(*[x for x in targets if x is not set_element]))))
print(result)
(note that the [x for x in targets if x != set_element]
is just the set of all other sets)
Your code example doesn't work because it's finding the intersection between all of the sets, which is 0 (since no element occurs everywhere). You want to find the difference between each set and the union of all other sets. For example:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
result =
for set_element in targets:
result.append(len(set_element.difference(set.union(*[x for x in targets if x is not set_element]))))
print(result)
(note that the [x for x in targets if x != set_element]
is just the set of all other sets)
edited Dec 18 '18 at 23:42
answered Nov 20 '18 at 1:30
Unsolved CypherUnsolved Cypher
495314
495314
1
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
1
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the!=
to anis not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)
– Unsolved Cypher
Dec 18 '18 at 23:43
add a comment |
1
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
1
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the!=
to anis not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)
– Unsolved Cypher
Dec 18 '18 at 23:43
1
1
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
This works great, and quickly. Thank you!
– SummerEla
Nov 20 '18 at 2:46
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
Unfortunately, I found an error in your solution. It returns an error when there is no difference between sets.
– SummerEla
Dec 18 '18 at 20:57
1
1
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the
!=
to an is not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)– Unsolved Cypher
Dec 18 '18 at 23:43
@SummerEla Good catch! I've updated the code, and now it works in that situation as well. I changed the
!=
to an is not
, so that it's every list is checked against other lists that are different objects rather than just those that have different values (since lists can be different objects but look identical)– Unsolved Cypher
Dec 18 '18 at 23:43
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%2f53384697%2fpython-symmetrical-difference-between-list-of-sets-of-strings%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
Is each string a single character? If not, are you going by whether the entire string occurs elsewhere, or just the character by character differences?
– Unsolved Cypher
Nov 20 '18 at 1:00
1
Each string contains at least six characters, and I would like to test the entire occurrence of the string. Perhaps I oversimplified my example, but I wasn't sure that would make a difference.
– SummerEla
Nov 20 '18 at 1:08