2017-05-30 1 views
3

Disons que j'ai ces ensembles numériquesTrouver des groupes de sous-ensembles numériques

a = {1, 2, 3} 
b = {2, 3, 4} 
c = {1, 5} 

Je veux trouver tous les groupes numériques distincts des ensembles. Le résultat serait

{1}, {2, 3}, {4}, {5} 

Mon approche naïve, qui ne fonctionne pas, est quelque chose comme ceci:

data = [{1, 2, 3}, {2, 3, 4}, {1, 5}] 
for i in range(1, 5): 
    s = set.intersection(*[x for x in data if i in x]) 
    print(s) 

qui retourne

set([1]) 
set([2, 3]) 
set([2, 3]) 
set([2, 3, 4]) 

qui pourrait facilement être dédupliquées mais ne donne pas le résultat attendu.

Comment puis-je obtenir uniquement les regroupements de nombres qui existent dans le sous-ensemble d'ensembles?

+0

Vous n'êtes pas sûr que votre algorithme fonctionne. Vous voulez probablement passer en revue les 2^3-1 sous-ensembles de [0,1,2] et regarder quels sont les éléments qui apparaissent dans chaque sous-ensemble et non dans le complément. – WNG

+4

Pouvez-vous clarifier les «regroupements de nombres qui existent dans le sous-ensemble de définit un peu plus loin? Quelle est votre idée du «groupement numérique distinct»? Parce que '{1}', '{4}' et '{5}' ne sont certainement pas des groupes d'aucune sorte. – zwer

Répondre

5

Votre code a deux problèmes:

  • Vous arrêtez à 5, mais range ne comprend pas l'arrêt si vous ne cochez pas pour 5.
  • Si une valeur est seulement dans un ensemble que vous besoin de créer un ensemble qui ne contient que cette valeur. Au moins, le résultat attendu semble être le comportement souhaité.

Donc, en fixant ces questions le code ressemblerait à ceci:

data = [{1, 2, 3}, {2, 3, 4}, {1, 5}] 
for i in range(1, 6): 
    useful_sets = [x for x in data if i in x] 
    if len(useful_sets) <= 1: 
     print(set([i])) 
    else: 
     s = set.intersection(*useful_sets) 
     print(s) 

# prints: 
# {1} 
# {2, 3} 
# {2, 3} 
# {4} 
# {5} 

Pour obtenir un complet (et non dupliqués) résultat que vous pouvez les stocker sous forme frozensets dans un ensemble:

data = [{1, 2, 3}, {2, 3, 4}, {1, 5}] 
res = set() 
for i in range(1, 6): 
    useful_sets = [x for x in data if i in x] 
    if len(useful_sets) <= 1: 
     res.add(frozenset([i])) 
    else: 
     s = set.intersection(*useful_sets) 
     res.add(frozenset(s)) 

print(res) 
# {frozenset({5}), frozenset({4}), frozenset({2, 3}), frozenset({1})} 

Lequel (sauf pour la commande) devrait être exactement ce que vous voulez.

+1

Au lieu d'un 'range' fixe, vous pouvez" décompresser "toutes les données et les réitérer' set.union (* data) ' – pylang