Как насчет этого:
from collections import Counter
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s3 = set([2, 3, 7])
s4 = set([2, 5, 9])
print([k for k,v in Counter((*s1,*s2,*s3,*s4)).items() if v == 1])
Даже если это выглядит красиво, так как это единственное, что нужно учитывать, это немного медленнее, чем ваш собственный подход:
In [85]: def nicefunc(sets):
...: return [k for k,v in Counter(itertools.chain.from_iterable(sets)).items() if v == 1]
...:
In [86]: def nicefunc2(sets):
...: return [k for k,v in Counter( [i for s in sets for i in s]).items() if v == 1]
...:
In [87]: def nicefunc3():
...: return [k for k,v in Counter((*s1,*s2,*s3,*s4)).items() if v == 1]
...:
In [88]: def myfunc(sets):
...: sd = set()
...: goners = set()
...: for s in sets:
...: still_ok = s - goners
...: sd = sd.symmetric_difference(still_ok)
...: goners = goners.union(s.difference(sd))
...: return sd
...:
In [89]: sets = [s1, s2, s3, s4]
In [90]: %timeit myfunc(sets)
2.25 µs ± 2.53 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [91]: %timeit nicefunc(sets)
3.64 µs ± 23 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [92]: %timeit nicefunc2(sets)
3.79 µs ± 11.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [94]: %timeit nicefunc3()
3.64 µs ± 18.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
ВыМожно также выбрать другой подход, который все еще является одним, но более быстрым:
In [152]: def coolfunc(sets):
...: return set.union(*[sets[i]-set.union(*sets[:i],*sets[i+1:]) for i in range(len(sets))])
In [153]: coolfunc(sets)
Out[153]: {1, 4, 5, 7, 9}
In [154]: %timeit coolfunc(sets)
3.34 µs ± 19.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Однако, как указал @VBrail, вы неправильно определили различие симметричных множеств в наборе множеств.Ниже приведен однострочник для расчета фактической симметричной разности наборов в коллекции, которая определяется как
. Симметричная разность набора содержит только элементы, которые находятся в нечетном числе наборов вколлекция Википедия
from functools import reduce
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s3 = set([2, 3, 7])
s4 = set([2, 5, 9])
sets = [s1,s2,s3,s4]
reduce(set.symmetric_difference, sets)
{1, 3, 4, 5, 7, 9}