IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

[Python 2.7] dictionnaire et liste de listes


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut [Python 2.7] dictionnaire et liste de listes
    Bonjour,

    Je me permets de solliciter votre aide pour ameliorer/corriger un script...
    A partir d'un dictionnaire le but est de créer des relations entre individus quand ils partagent les mêmes éléments.
    Je génère un output pour visualiser les liens (network).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    populations3={'ind1':['H','R1b'],'ind2':['H','R1b'],'ind3':['K1a','R1b'],'ind4':['K1a','J2a'], 'ind5':['H','R1b']}
     
    list_ind = list(populations3.keys())	
    n=len(list_ind)
    net=[]
    net2=[]
    for i in range(n) :
    	for j in range(n) :
    		list1 = populations3[list_ind[i]]
    		list2 = populations3[list_ind[j]]
    		#a = common_elements(list1_ind,list2_ind)
    		en_commun=[elt for elt in list1 if elt in list2]
    		en_commun2='_'.join(en_commun)
    		net=list_ind[i],list_ind[j],en_commun2
    		net2.append(net)
     
    net3=[]
    for i in net2:
    	if i[2] != '':
    		net3.append(i)#exclut les echantillons qui n ont pas de relations
    for i in net3:
    	print i
    Le résultat est correct, il affiche les ID des individus qui partagent les même éléments. Néanmoins, si on se focalise sur les individus qui partagent H_R1b voilà le resultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ('ind5', 'ind5', 'H_R1b')
    ('ind5', 'ind1', 'H_R1b')
    ('ind5', 'ind2', 'H_R1b')
    ('ind1', 'ind5', 'H_R1b')
    ('ind1', 'ind1', 'H_R1b')
    ('ind1', 'ind2', 'H_R1b')
    ('ind2', 'ind5', 'H_R1b')
    ('ind2', 'ind1', 'H_R1b')
    ('ind2', 'ind2', 'H_R1b')
    Il y a des redondances que je n arrive pas à supprimer:
    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ('ind1', 'ind1', 'H_R1b')
    ('ind2', 'ind2', 'H_R1b')
    ('ind5', 'ind5', 'H_R1b')
    De plus je cherche a réduire le nombre de liens dont certains sont inutiles dans mon cas par exemple entre ind1 et ind 2 le code affiche: ('ind2', 'ind1', 'H_R1b'), ('ind1', 'ind2', 'H_R1b'), une seule de ces relations suffirait.
    En gros si on se focalise seulement sur les Individus qui partagent H1,R1b je cherche à avoir comme résultat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    populations3={'ind1':['H','R1b'],'ind2':['H','R1b'], 'ind5':['H','R1b']}
    ('ind1', 'ind2', 'H_R1b')
    ('ind1', 'ind5', 'H_R1b')
    ('ind2', 'ind5', 'H_R1b')
    Ce qui dans l'idée revient au résultat affiche plus haut mais avec une réduction du nombre de liens (redondance)
    J'espère ne pas être trop confus.

    Merci pour votre aide

  2. #2
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut, l'idéal serait de créer un dictionnaire temporaire en inversant les clés, valeurs de ton dictionnaire initial, puis à partir de lui, créer les combinaisons de tes identifiants.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from itertools import combinations
     
    valeurs = dict()
    for c, liste in populations3.items() :
        t = tuple(sorted(liste))
        valeurs.setdefault(t, []).append(c)
     
     
    for c, ids in valeurs.items() :
        if len(ids) > 2 :
            combs = combinations(sorted(ids), 2)
            for comb in combs :
                print comb, c
        else :
            print tuple(ids), c

  3. #3
    Membre chevronné
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mai 2003
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 290
    Par défaut
    Bonjour,
    Je ne sais pas si j'ai tout compris mais bon.

    Pour faire la même chose que ton script en évitant les doublons :
    (pas testé en python 2.7)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    populations3={'ind1':['H','R1b'],'ind2':['H','R1b'],'ind3':['K1a','R1b'],'ind4':['K1a','J2a'], 'ind5':['H','R1b']}
    list_ind = list(populations3.keys())	
    n=len(list_ind)
    net=[]
    x=1
    for k in list_ind:
    	for i in range(x,n):
    		en_commun=[elt for elt in populations3[k] if elt in populations3[list_ind[i]]]
    		if len(en_commun):
    			net.append([k,list_ind[i],'_'.join(en_commun)])
    	x+=1
     
    for v in net:
    	print v

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 47
    Par défaut
    Merci beaucoup pour votre aide précieuse.
    pierjean peux-tu m'éclairer sur le if s'il te plait?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if len(en_commun):		
    			net.append([k,list_ind[i],'_'.join(en_commun)])
    encore merci

  5. #5
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    j'y vais de ma proposition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    net, populations3 = [], {
       'ind1': ['H',  'R1b'],
       'ind2': ['H',  'R1b'],
       'ind3': ['K1a','R1b'],
       'ind4': ['K1a','J2a'],
       'ind5': ['H',  'R1b']
    }
     
    for i in populations3:
       for j in populations3:
          if i == j:
             continue
          en_commun = '_'.join([elt for elt in populations3[i] if elt in populations3[j]])
          if en_commun and (i,j,en_commun) not in net and (j,i,en_commun) not in net:
                net.append((i,j,en_commun))
    • on élimine simplement les cas comme ('ind1', 'ind1', 'H_R1b') en vérifiant si i == j et en sautant au prochain tour de boucle
    • plus bas on teste en un seul if si en_commun n'est pas vide et si il n'y a pas déjà un résultat similaire dans net
    • on en profite pour alléger un peu le code des variables intermédiaires, de l'utilisation des indices, etc.


    et le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    [('ind5', 'ind1', 'H_R1b'),
     ('ind5', 'ind3', 'R1b'),
     ('ind5', 'ind2', 'H_R1b'),
     ('ind4', 'ind3', 'K1a'),
     ('ind1', 'ind3', 'R1b'),
     ('ind1', 'ind2', 'H_R1b'),
     ('ind3', 'ind2', 'R1b')]

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Pour avoir à la fois :
    - pas de doublons ("ind1", "ind1", ...)
    - pas de doublons ("ind1","ind2",...) et ("ind2","ind1", ...)
    il suffit de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(n) :
    	for j in range(n) :
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(n) :
    	for j in range(i+1,n) :
    j démarrant à i+1, tu es sûr qu'il ne sera pas égal à i déja. Et ensuite on ne regarde que le j plus grand que i. Car pour les plus petits et bien la combinaison dans l'autre sens a déjà ét examinée.

    Il n'y a strictement rien de plus a ajouter ...

Discussions similaires

  1. liste in liste python
    Par rosef dans le forum Général Python
    Réponses: 19
    Dernier message: 28/09/2013, 00h10
  2. Réponses: 0
    Dernier message: 05/06/2012, 13h13
  3. Créer un dictionnaire à partir d'une liste
    Par jouclar dans le forum Général Python
    Réponses: 7
    Dernier message: 25/04/2012, 22h09
  4. Python et les listes de listes
    Par gb.gambas dans le forum Général Python
    Réponses: 3
    Dernier message: 28/03/2009, 15h12
  5. Regrouper une liste en liste de listes
    Par West01 dans le forum Prolog
    Réponses: 12
    Dernier message: 14/03/2008, 14h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo