Różnica symetryczna.

0

Mam trzy zbiory składające się z imion i nazwisk osób uczęszczających na poszczególne przedmioty. Mam wyświetlić osoby uczęszczające na tylko jeden przedmiot. Chcę skorzystać z różnicy symetrycznej ale od dłuższego czasu szukam jak zrobić, zdefiniować różnice symetryczną dla trzech zbiorów. A^B^C nie daje pożądanego wyniku.

0

Użyj symmetric_difference i difference:

import itertools

def symm_diff_three(a, b, c):
	tmp = a.union(b.union(c))

	tmp1 = [x.intersection(y) for x, 
		y in itertools.combinations([a, b, c], 2)]
	tmp2 = tmp1[0].union(tmp1[1].union(tmp1[2]))
	return tmp.symmetric_difference(tmp2)
	

def main():
	a = set([11, 1 ,5])
	b = set([1, 5, 3])
	c = set([3, 9, 1])
	print(symm_diff_three(a, b, c)) # -> 9, 11

	
if __name__ == '__main__':
	main()

EDYCJA: Zmieniłem rozwiązanie, trzeba znaleźć sumę wszystkich zbiorów, potem wszystkie możliwe dwuelementowe przecięcia, i od sumy odjąc te przecięcia.

EDYCJA2: W zasadzie robiąc takie coś powinno sie uogólnić na dowolną liczbę zbiorów:

import itertools
from functools import reduce

def set_union(x, y):
	return x.union(y)

def symm_diff(*args):
	tmp = reduce(set_union, args)
	tmp1 = [x.intersection(y) for x, 
		y in itertools.combinations(args, 2)]
	tmp2 = reduce(set_union, tmp1)
	return tmp.symmetric_difference(tmp2)
1

Symetryczna różniąca dowolnej liczby zbiorów składa się z tych elementów, które występują w nieparzyście wielu z tych zbiorów, toteż nic dziwnego, że Twój początkowy pomysł nie działa. Jeśli jednak chcesz rozwiązać to zadanie sprawnie, to najlepszą metodą jest oczywiście zliczenie elementów i wykluczenie tech, które występują co najmniej dwa razy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1