J'ai une liste qui contient plusieurs ensembles de chaînes, et je voudrais trouver la différence symétrique entre chaque chaîne et les autres chaînes de l'ensemble.

Par exemple, j'ai la liste suivante:

targets = [{'B', 'C', 'A'}, {'E', 'C', 'D'}, {'F', 'E', 'D'}]

Pour ce qui précède, la sortie souhaitée est:

[2, 0, 1]

Parce que dans le premier ensemble, A et B ne se trouvent dans aucun des autres ensembles, pour le deuxième ensemble, il n'y a pas d'éléments uniques dans l'ensemble, et pour le troisième ensemble, F ne se trouve dans aucun des autres ensembles.

J'ai pensé aborder cela à l'envers; trouver l'intersection de chaque ensemble et soustraire la longueur de l'intersection de la longueur de la liste, mais set.intersection (*) ne semble pas fonctionner sur des chaînes, donc je suis bloqué:

set1 = {'A', 'B', 'C'}
set2 = {'C', 'D', 'E'}
set3 = {'D', 'E', 'F'}

targets = [set1, set2, set3]

>>> set.intersection(*targets)
set()
4
SummerEla 20 nov. 2018 à 03:49

3 réponses

Meilleure réponse

Le problème que vous rencontrez est qu'il n'y a pas de chaînes partagées par les trois ensembles, donc votre intersection apparaît vide. Ce n'est pas un problème de chaîne, cela fonctionnerait de la même manière avec des nombres ou tout ce que vous pouvez mettre dans un ensemble.

La seule façon que je vois pour faire un calcul global sur tous les ensembles, puis l'utiliser pour trouver le nombre de valeurs uniques dans chacun est de compter d'abord toutes les valeurs (en utilisant collections.Counter), puis pour chaque ensemble, compter le nombre de valeurs qui n'apparaissent qu'une seule fois dans le décompte global.

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]
1
Blckknght 20 nov. 2018 à 01:34

Votre exemple de code ne fonctionne pas car il trouve l'intersection entre tous les ensembles, qui vaut 0 (car aucun élément ne se produit partout). Vous voulez trouver la différence entre chaque ensemble et l'union de tous les autres ensembles. Par exemple:

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)

(notez que le [x for x in targets if x != set_element] n'est que l'ensemble de tous les autres ensembles)

1
Unsolved Cypher 18 déc. 2018 à 23:42

Essayez quelque chose comme ci-dessous:

Obtenez une différence symétrique avec chaque ensemble. Puis intersecter avec l'ensemble d'entrée donné.

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)
1
Pavan Chandaka 20 nov. 2018 à 01:29