Python:字符串集列表之间的对称差异
Python: Symmetrical Difference Between List of Sets of Strings
我有一个包含多组字符串的列表,我想找出每个字符串与该组中其他字符串之间的对称差异。
例如,我有以下列表:
targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]
对于上述,期望的输出是:
[2, 0, 1]
因为在第一个集合中,A和B在任何其他集合中都找不到,对于第二个集合,集合中没有唯一元素,对于第三个集合,在任何一个集合中都找不到F其他套。
我考虑过向后处理这个问题;找到每个集合的交集并从列表的长度中减去交集的长度,但是 set.intersection(*) 似乎不适用于字符串,所以我被卡住了:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
>>> set.intersection(*targets)
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)
您的代码示例不起作用,因为它正在寻找所有集合之间的交集,即 0(因为没有元素出现在所有地方)。您想要找出每个集合与所有其他集合的并集之间的差异。例如:
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)
(注意 [x for x in targets if x != set_element]
只是所有其他集合的集合)
您遇到的问题是所有三个集合都没有共享字符串,因此您的 intersection
是空的。这不是字符串问题,它对数字或您可以放入集合中的任何其他内容都一样。
我看到对所有集合进行全局计算,然后使用它来查找每个集合中唯一值的数量的唯一方法是首先计算所有值(使用 collections.Counter
),然后对于每个集合,计算在全局计数中只出现一次的值的数量。
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]
我有一个包含多组字符串的列表,我想找出每个字符串与该组中其他字符串之间的对称差异。
例如,我有以下列表:
targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]
对于上述,期望的输出是:
[2, 0, 1]
因为在第一个集合中,A和B在任何其他集合中都找不到,对于第二个集合,集合中没有唯一元素,对于第三个集合,在任何一个集合中都找不到F其他套。
我考虑过向后处理这个问题;找到每个集合的交集并从列表的长度中减去交集的长度,但是 set.intersection(*) 似乎不适用于字符串,所以我被卡住了:
set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}
targets = [set1, set2, set3]
>>> set.intersection(*targets)
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)
您的代码示例不起作用,因为它正在寻找所有集合之间的交集,即 0(因为没有元素出现在所有地方)。您想要找出每个集合与所有其他集合的并集之间的差异。例如:
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)
(注意 [x for x in targets if x != set_element]
只是所有其他集合的集合)
您遇到的问题是所有三个集合都没有共享字符串,因此您的 intersection
是空的。这不是字符串问题,它对数字或您可以放入集合中的任何其他内容都一样。
我看到对所有集合进行全局计算,然后使用它来查找每个集合中唯一值的数量的唯一方法是首先计算所有值(使用 collections.Counter
),然后对于每个集合,计算在全局计数中只出现一次的值的数量。
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]