[Python] intersection, combinations ?

intersection, combinations ? [Python] - Python - Programmation

Marsh Posté le 02-11-2011 à 20:19:45    

Bonsoir,
J'ai un petit problème d'algo que j'arrive pas a résoudre, j'ai la tête qui chauffe...
Je sais que certains codeurs passent par ici.
 
J'ai un dico avec une liste d'objets dans chaque clé, genre :
Code :
 

Code :
  1. allGroups = {"property1":["object1", "object2", "object3", "object4"], "property2":["object1, "object2", "object4"], "property3":["object2", "object3", "object4"], "property4":["object1"], "property5":[]}


 
J'aimerais a partir de ça, générer des "groupes" d'objects qui étaient dans chaque keys.
C'est a dire ici :
 
result1 = ["object1"] a la property1, property2, property4
result2 = ["object2", "object4"] a la property1, property2, property3
result3 = ["object3"] a la  property1, property3
etc etc....
 
Chaque objet ne peut pas être dans un autre groupe.
 
Et évidement, de quoi retrouver les propriétés d'un result, donc, le sortir en dico, genre :

Code :
  1. { ["property1", "property2", "property4"]:["object1"]}
  2. { ["property1", "property2", "property3"]:["object2", "object4"]}


par exemple, etc etc...
 
Un chemin a me donner ? Sans parser chaque object évidement.
J'ai regarde du cote des set intersection du coup, puis dans les itertools.combinations, ben ça devient chaud...  
Merci


Message édité par bigbossfr le 03-11-2011 à 00:47:26
Reply

Marsh Posté le 02-11-2011 à 20:19:45   

Reply

Marsh Posté le 03-11-2011 à 10:39:49    

Il faut parcourir toutes les éléments et construire un dictionnaire "inverse", ca doit pouvoir se faire en 6/7 lignes.
 

Spoiler :

allGroups = {"property1":["object1", "object2", "object3", "object4"], "property2":["object1", "object2", "object4"], "property3":["object2", "object3", "object4"], "property4":["object1"], "property5":[]}
 
dicoInverse={}
for p in allGroups.keys():
    for o in allGroups[p]:
        if dicoInverse.has_key(o):
            dicoInverse[o].append(p)
        else:
            dicoInverse[o]=[]
            dicoInverse[o].append(p)
 
print str(dicoInverse)


Message édité par philippe06 le 03-11-2011 à 11:44:02

---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
Reply

Marsh Posté le 03-11-2011 à 12:27:48    

Ce n'est pas exactement ceci que je veux.
La ta fonction print :
 

Code :
  1. {'object1': ['property1', 'property2', 'property4'], 'object2': ['property1', 'property2', 'property3'], 'object3': ['property1', 'property3'], 'object4': ['property1', 'property2', 'property3']}


 
Hors, je veux en keys les properties avec une liste d'objets dedans...
La on a l'objet 2 et 4 qui se reproduisent.
 
De plus, c'est pas possible sans parcourir tout les elements ? Avec des sets ou autres..
Cest que je peux en avoir 10 000...

Message cité 2 fois
Message édité par bigbossfr le 03-11-2011 à 12:30:35
Reply

Marsh Posté le 03-11-2011 à 14:22:33    

bigbossfr a écrit :


De plus, c'est pas possible sans parcourir tout les elements ? Avec des sets ou autres..
Cest que je peux en avoir 10 000...


 
Ben tu sais, même si tu utilises des méthodes poussées comme des itertools il y aura quand-même parsing (même si c'est l'itertools qui le fait en caché !!!)
 
Déjà ce premier code permet d'extraire les objets

Code :
  1. o=[]
  2. for v in allGroups.values():
  3.     o+=v


 
J'ai essayé d'éviter la boucle en passant par un reduce mais j'ai pas réussi. Quoi qu'il en soit, en fin de boucle tu as tous tes objets dans "o" (avec les redondances mais tu peux les supprimer par un set)
 
Ensuite cette seconde itération te crée un dico par objet

Code :
  1. all={}
  2. for x in set(o):
  3.     if x not in all.keys():
  4.         all[x]=[]
  5.     for (k, v) in allGroups.items():
  6.         if x in v: all[x].append(k)


En fin d'itération, tu as all={'object1': ['property1', 'property2', 'property4'], 'object2': ['property1', 'property2', 'property3'], 'object3': ['property1', 'property3'], 'object4': ['property1', 'property2', 'property3']} (tout comme le code de philippe06)
 
Ensuite j'ai tenté de créer un dico en partant de "all" mais en inversant "k" et "v" de cette façon

Code :
  1. result={}
  2. for (k, v) in all.items():
  3.     if v not in result.keys():
  4.         result[v]=[]
  5.     result[v].append(k)


Ce qui aurait donné result= { ["property1", "property2", "property4"]:["object1"], ["property1", "property2", "property3"]:["object2", "object4"]} comme tu le veux mais il semble qu'en python2.6 (ma version) on ne puisse pas créer de dico où la clef serait une liste comme me l'a montré l'essai suivant

Code :
  1. result={ [1, 2, 3] : "toto"}


et où j'ai eu la réponse "TypeError: list objects are unhashable"
 
Donc voilà. Peut-être qu'en python3 on peut faire mais quoi qu'il en soit, tu ne pourras pas éviter de parser ton objet. Tout ce que tu peux faire sera d'éviter les parsing inutiles ou redondants...

Reply

Marsh Posté le 03-11-2011 à 15:02:15    

bigbossfr a écrit :

Ce n'est pas exactement ceci que je veux.
La ta fonction print :
 


Code :
  1. {'object1': ['property1', 'property2', 'property4'], 'object2': ['property1', 'property2', 'property3'], 'object3': ['property1', 'property3'], 'object4': ['property1', 'property2', 'property3']}


Hors, je veux en keys les properties avec une liste d'objets dedans...
La on a l'objet 2 et 4 qui se reproduisent.
 
De plus, c'est pas possible sans parcourir tout les elements ? Avec des sets ou autres..
Cest que je peux en avoir 10 000...

Code :
  1. allGroups = {"property1":["object1", "object2", "object3", "object4"], "property2":["object1", "object2", "object4"], "property3":["object2", "object3", "object4"], "property4":["object1"], "property5":[]}
  2. dicoInverse={}
  3. for p in allGroups.keys():
  4.     for o in allGroups[p]:
  5.         if dicoInverse.has_key(o):
  6.             dicoInverse[o].append(p)
  7.         else:
  8.             dicoInverse[o]=[]
  9.             dicoInverse[o].append(p)
  10. liste={}
  11. for dk in dicoInverse.keys():
  12.     if liste.has_key(str(dicoInverse[dk])):
  13.         liste[str(dicoInverse[dk])].append(dk)
  14.     else:
  15.         liste[str(dicoInverse[dk])]=[]
  16.         liste[str(dicoInverse[dk])].append(dk)
  17. liste_finale={}
  18. for lk in liste.keys():
  19.     liste_finale[str(liste[lk])]=lk
  20. print liste_finale


Je viens de saisir que le problème vient du fait que la structure de donnée dictionnaire en Python n'est pas adapté au problème. Je suppose que la bonne façon de faire est de numéroter les objets et les propriétés et de travailler avec des vecteurs d'entier ... ou une matrice avec les propriété et les objets.


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
Reply

Marsh Posté le 03-11-2011 à 16:00:45    

Merci a vous 2, Sve@r et philippe06. C'est niquel, j'ai tout ce qu'il faut !
Au final pas besoin de itertools ou autre truc complique.
Merci encore  :o

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed