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 :

Besoin d'aide exercice Python [Python 3.X]


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2022
    Messages : 2
    Par défaut Besoin d'aide exercice Python
    Bonjour,
    J'aide du mal avec cet exercice, quelqu'un pourrait m'aider svp ?

    Écrire une fonction jointure(bdd1,champ1,bdd2,champ2) qui renvoie une nouvelle base. Pour que cela soit
    possible, il faut qu’aucun champs de bdd1 ne soit aussi un champ de bdd2. La nouvelle base est construite

    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
    ainsi :
    bdd1 =
    [{'int': 1, 'str': 'a'},
    {'int': 2, 'str': 'a'},
    {'int': 3, 'str': 'b'}
    {'int': 4, 'str': 'c']
     
    bdd2 =
    [{'string': 'a', 'float': 3.14},
    {'string': 'b', 'float': 2.72},
    {'string': 'b', 'float': 1.41}]
     
    jointure(bdd1,"str",bdd2,"string")
    >>>>[{'int': 1, 'str': 'a', 'float': 3.14},
    {'int': 2, 'str': 'a', 'float': 3.14},
    {'int': 3, 'str': 'b', 'float': 2.72},
    {'int': 3, 'str': 'b', 'float': 1.41}]

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par johnllol Voir le message
    J'aide du mal avec cet exercice, quelqu'un pourrait m'aider svp ?
    Oui on est là pour ça. Mais la condition préalable à toute aide est que tu commences par montrer ce que tu as fait.

    Si tu as du mal à commencer (ça peut arriver), commence par traiter chaque info de bdd1 et voir comment tu peux ensuite t'en servir pour en extraire le champ qui sert de jointure sur la bdd2...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2022
    Messages : 2
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    Oui on est là pour ça. Mais la condition préalable à toute aide est que tu commences par montrer ce que tu as fait.

    Si tu as du mal à commencer (ça peut arriver), commence par traiter chaque info de bdd1 et voir comment tu peux ensuite t'en servir pour en extraire le champ qui sert de jointure sur la bdd2...

    Re, j'ai commencé avec ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def jointure(bdd1, champ1, bdd2, champ2):
        final_bdd = []
     
        # Pour chaque champ de bdd1
        for bdd1_index, bdd1_element in enumerate(bdd1):
            for bdd2_index, bdd2_element in enumerate(bdd2):
                to_append = {}
                # Si un champ similaire existe dans bdd2
                if bdd1[bdd1_index][champ1] == bdd2[bdd2_index][champ2]:
                    to_append = bdd1[bdd1_index]
                    to_append[str(list(bdd2_element)[1:][0])] = [value for key, value in bdd2[bdd2_index].items() if key not in champ2][0]
                    final_bdd.append(to_append)
     
        return final_bdd
    Le problème étant que lorsqu'une valeur de bdd1 a été trouvé dans bdd2 et ajouté à final_bdd, on continue avec la valeur de bdd1 et donc on assigne la dernière valeur de bdd2 trouvé, ce qui écrase la précédente (supposition):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [{'int': 1, 'str': 'a', 'float': 3.14}, {'int': 2, 'str': 'a', 'float': 3.14}, {'int': 3, 'str': 'b', 'float': 1.41}, {'int': 3, 'str': 'b', 'float': 1.41}]

  4. #4
    Invité
    Invité(e)
    Par défaut
    Salut !

    Tu n'étais pas loin ! Il ne faut JAMAIS oublié que les listes ou les dictionnaires doivent être dupliqués correctement, si on s'y prend mal voici ce que ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> dico1 = {'int': 1, 'str': 'a'}
     
    >>> dico = dico1
     
    >>> dico['toto']=0+0
     
    >>> dico
    {'int': 1, 'str': 'a', 'toto': 0}
     
    >>> dico1
    {'int': 1, 'str': 'a', 'toto': 0}
    Il existe tout un tas de méthode pour cloner une liste, le plus simple est souvent d'utiliser le module copy avec la fonction deepcopy (pour dupliquer des listes imbriquées dans des listes...). Voici un site qui référence toutes (ou presque) les méthodes de clonage de liste : https://therenegadecoder.com/code/ho...multiplication

    Ici il suffit d'utiliser la fonction copy() des dictionnaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def test():
    	bdd = []
    	for dico1 in bdd1:
    		for dico2 in bdd2:
    			if dico2['string']==dico1['str']:
    				dico = dico1.copy()
    				dico['float']=dico2['float']
    				bdd.append(dico)
    	return bdd
    J'espère ne pas me tromper...

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par johnllol Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [{'int': 1, 'str': 'a', 'float': 3.14}, {'int': 2, 'str': 'a', 'float': 3.14}, {'int': 3, 'str': 'b', 'float': 1.41}, {'int': 3, 'str': 'b', 'float': 1.41}]
    En tout cas, par rapport à l'exemple que tu as montré au premier post, ton code fournit un résultat identique...

    Citation Envoyé par LeNarvalo Voir le message
    J'espère ne pas me tromper...
    Dans l'absolu non, ce que tu dis est vrai (sauf à conseiller systématiquement de passer par le module "copy" en disant que c'est "le plus simple" car le plus simple est plutôt de ne pas utiliser un module quand ce n'est pas nécessaire)
    Mais dans le cas présent je n'ai pas trouvé d'exemple où ce danger inhérent à la copie superficielle amène un résultat erroné...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Invité
    Invité(e)
    Par défaut
    Okay !

    J'utilise quasiment jamais le module copy qui plus est ^^'. Je me suis dit que deepcopy était plus facile, pas besoin de comprendre.



    Je me permets un petit squattage de topic pour pas changer, si t'as envie d'y répondre Sve@r :

    1. deepcopy fonctionne de façon récursive ? C'est pas terrible...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def t():
    	l = []
    	for i in range(300):
    		m = [l]
    		l = [m]
    	x = copy.deepcopy(l)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RecursionError: maximum recursion depth exceeded while calling a Python object
    2. La méthode la plus commune où tu utilises une boucle et une pile faite maison, elle porte un nom ? (Alzheimer ...)

    3. Je te mets au défi de faire une fonction de copie profonde sans récursion et sans Google ! (Chui toujours une quiche ! Que se soit pour résoudre un labyrinthe ou faire ça, mon cerveau sature...)

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Je me suis dit que deepcopy était plus facile, pas besoin de comprendre.
    Comprendre l'utilité de deepcopy c'est d'abord comprendre les soucis de la copie de base donc déjà apprendre à faire une copie de base de façon directe.

    Citation Envoyé par LeNarvalo Voir le message
    1. deepcopy fonctionne de façon récursive ? C'est pas terrible...
    Ben oui... ben tant pis.

    Citation Envoyé par LeNarvalo Voir le message
    2. La méthode la plus commune où tu utilises une boucle et une pile faite maison, elle porte un nom ? (Alzheimer ...)
    Non, ce n'est pas la méthode Alzheimer (ouais c'est bon j'ai compris la vanne). Je ne pense pas qu'elle ait de nom. On peut la retrouver en tapant "simuler récursivité pile" dans les moteurs et est détaillée dans le bouquin "Méthodes de programmation" de Bertrand Meyer et Claude Baudoin (éditions Eyrolles)

    Citation Envoyé par LeNarvalo Voir le message
    3. Je te mets au défi de faire une fonction de copie profonde sans récursion et sans Google ! (Chui toujours une quiche ! Que se soit pour résoudre un labyrinthe ou faire ça, mon cerveau sature...)
    Un défi? Je ne suis pas certain d'avoir quelque chose à te prouver... mais effectivement c'est intéressant. J'aimerais que Tyrtamos passe par ici je pense que ça lui plairait aussi.
    Déjà je viens de refaire un ersatz de deepcopy en récursif...
    Code python : 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #!/usr/bin/env python3
    # coding: utf-8
     
    # Immutabilité
    def isMutable(truc):
    	# Si le truc n'est pas hashable il est mutable
    	try:
    		hash(truc)
    	except TypeError:
    		return True
    	else:
    		# Sinon il est immuable
    		return False
    	# try
    # isMutable()
     
    # Copie (récursive)
    def copie_r(truc):
    	# Si le truc n'est pas mutable il peut être retourné directement
    	if not isMutable(truc): return truc
     
    	# Ok, copie. Déjà il faut distinguer deux cas...
    	if isinstance(truc, dict):
    		# Le dict est particulier
    		return truc.__class__((k, copie_r(v)) for (k, v) in truc.items())
    	else:
    		# Le list ou set c'est la même chose
    		return truc.__class__(map(copie_r, truc))
    	# if
    # copie_r()
     
    # Copie (pile)
    def copie_p(truc): pass
     
    # Test
    base={1 : "XXX", 2 : [1, 2, {3, 4}], 3 : {4, 5, (6, 7)}, 4 : (7, 8, [9, 0])}
    cp=copie_r(base)
    base[2].append("yyy")
    base[3].add("zzz")
    print(base, type(base), id(base))
    print(cp, type(cp), id(cp), id(cp) != id(base))

    Le plus difficile c'est maintenant de remplacer la récursivité par une pile...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Invité
    Invité(e)
    Par défaut
    Merci pour tes réponses et les annotations dans ton code !

    Un défi? Je ne suis pas certain d'avoir quelque chose à te prouver...
    Chui persuadé que tu t'es bien amusé à me montrer ton skill quand même !
    C'est super propre ! Je crois avoir compris le plus gros (en grande partie grace à Google), sauf le __class__(...) , ça créé une nouvelle variable identique à truc grosso-modo ? C'est une autre façon de faire une copie propre ?

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    et les annotations dans ton code !
    C'est mon habitude. Quand je conseille aux posteurs de commenter, c'est déjà à la base parce que moi je commente toujours ce que je fais.
    Mais je réfléchis à la pile depuis hier, je n'ai toujours pas trouvé.

    Citation Envoyé par LeNarvalo Voir le message
    C'est super propre ! Je crois avoir compris le plus gros (en grande partie grace à Google), sauf le __class__(...) , ça créé une nouvelle variable identique à truc grosso-modo ? C'est une autre façon de faire une copie propre ?
    Exact, ça reproduit ce que tu reçois. Car tu n'es pas obligé de recevoir un dict/list/set originel. Tu peux très bien en recevoir un dérivé...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class toto(dict): pass
     
    base=toto(((1, "xxx"), (2, [1, 2, {3, 4}]), (3, {4, 5, (6, 7)}), (4, (7, 8, [9, 0]))))
    cp=copie_r(base)
    Et ce qui est bien, c'est que isinstance() accepte de reconnaitre comme vrai un truc qui hérite de ce qu'on lui demande de reconnaitre. Donc si "toto" hérite de "dict", isinstance(truc, dict) sera quand-même vrai.

    Mais j'ai parlé d'ersatz car le vrai deepcopy() peut aussi copier des objets complexes et là, je ne sais pas du tout comment il s'y prend...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import copy
     
    class toto:
    	__slots__=("a",)
    	def __init__(self):
    		self.a = list(range(3))
     
    m = toto()
    print(m.a)
     
    m2=copy.deepcopy(m)
    print(m2.a)
    print(id(m), id(m.a))
    print(id(m2), id(m2.a))
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Invité
    Invité(e)
    Par défaut
    Merci encore pour ces explications ! =)

    Mais je réfléchis à la pile depuis hier, je n'ai toujours pas trouvé.
    Peut-être que tu peux te limiter uniquement à des listes de listes ?

    J'ai bien une idée que je n'ai pas réussi à formuler en pseudo-code qui se reposerait là dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class toto():
    	def __init__(self,obj,ind):
    		self.obj = obj
    		self.ind = ind #Un tuple d'indexes, exemple : LISTE = [[42, [33, 72, [2], 15]]] la liste [2] -> (0, 1, 2)
    new_liste = []
    LISTE = [truc = toto( liste_originale, (0) ), ]
    tant que LISTE :
    --remplir LISTE avec les sublistes (truc.obj)
    --truc = toto( element, (0,0,42,12,1) ) #exemple
    --ajouter truc à new_liste[0][0][42][12][1]

    Idée très brouillonne...

  11. #11
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 743
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Mais j'ai parlé d'ersatz car le vrai deepcopy() peut aussi copier des objets complexes et là, je ne sais pas du tout comment il s'y prend...
    Il y a les sources (et c'est bien plus compliqué que çà).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin d'aide sur python, exercices sur les fichiers
    Par Mini-minimoys dans le forum Général Python
    Réponses: 6
    Dernier message: 21/11/2015, 18h37
  2. aide exercice python
    Par brunette83 dans le forum Général Python
    Réponses: 10
    Dernier message: 21/11/2012, 08h36
  3. aide exercice python
    Par cedric190985 dans le forum Général Python
    Réponses: 2
    Dernier message: 24/03/2010, 12h57

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