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 :

Les dictionnaires en compr�hension ne marchent pas pour les sous-dictionnaires [Python 3.X]


Sujet :

Python

  1. #1
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2006
    Messages
    12 860
    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 860
    Billets dans le blog
    1
    Par d�faut Les dictionnaires en compr�hension ne marchent pas pour les sous-dictionnaires
    Bonjour
    Je viens de remarquer que dans un dictionnaire en compr�hension, on ne peut pas utiliser une variable d�finie dans un sous-dictionnaire dans le dictionnaire "parent".

    Exemple: je cr�e un dictionnaire o� chaque cl� sera associ�e � un tuple de sa valeur
    Code python : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    dd={k : tuple(range(k+1)) for k in range(1, 6)}
    print(dd)		# {1: (0, 1), 2: (0, 1, 2), 3: (0, 1, 2, 3), 4: (0, 1, 2, 3, 4), 5: (0, 1, 2, 3, 4, 5)}
    Jusque l�, pas de probl�me.

    Mais si je cherche � d�placer chaque tuple dans un sous-dictionnaire...
    Code python : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    dd={k : {"data" : tuple(range(k+1)) for k in range(1, 6)}}
    print(dd)
    ...l� o� je m'attendais � avoir {1: {"data" : (0, 1)}, 2: {"data" : (0, 1, 2)}, 3: {"data" : (0, 1, 2, 3)}, 4: {"data" : (0, 1, 2, 3, 4)}, 5: {"data" : (0, 1, 2, 3, 4, 5)}} j'ai eu un NameError: name 'k' is not defined.

    Effectivement avec le recul c'est compr�hensible. Le sous-dictionnaire �tant probablement g�n�r� � part, la variable "k" ne remonte pas sur le parent. Mais sur le coup j'ai �t� un peu surpris.

    PS : en fait, m�me pas besoin de sous-dictionnaire. Une simple superposition de cast suffit � reproduire le souci.
    Code python : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    d1={k : tuple(range(k+1)) for k in range(1, 6)}			# ok
    d2={k : tuple(tuple(range(k+1)) for k in range(1, 6))}		# Erreur
    Si quelqu'un a un avis...
    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]

  2. #2
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 259
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 259
    Par d�faut
    Hello,

    Dans ton code qui ne fonctionne pas :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    dd={k : {"data" : tuple(range(k+1)) for k in range(1, 6)}}
    L'interpr�teur voit en r�alit� deux compr�hensions distinctes et imbriqu�es:


    1. La compr�hension "externe" : {k : ... for k in range(1, 6)}
    2. La compr�hension "interne" : {"data" : tuple(range(k+1)) for k in range(1, 6)}


    La compr�hension interne cr�e sa propre "bulle" (sa propre port�e). Quand elle essaie d'acc�der � k pour faire range(k+1), elle regarde dans sa bulle, ne le trouve pas, et ne va pas chercher dans la bulle "s�ur" de la compr�hension externe. D'o� le NameError !

    Pour obtenir le r�sultat que tu veux, il ne faut en r�alit� cr�er qu'une seule et unique compr�hension.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    dd = {k: {"data": tuple(range(k+1))} for k in range(1, 6)}
    Citation Envoy� par interpr�teur
    In [1]: dd = {k: {"data": tuple(range(k+1))} for k in range(1, 6)}


    In [2]: dd
    Out[2]:
    {1: {'data': (0, 1)},
    2: {'data': (0, 1, 2)},
    3: {'data': (0, 1, 2, 3)},
    4: {'data': (0, 1, 2, 3, 4)},
    5: {'data': (0, 1, 2, 3, 4, 5)}}
    L'expression {"data": tuple(range(k+1))} n'est pas une compr�hension de dictionnaire (il n'y a pas de for � l'int�rieur). C'est ce qu'on appelle un litt�ral de dictionnaire.

    Je pense que ta source d'erreur est le fait d'avoir d�j� fait du python 2.x
    Celui qui trouve sans chercher est celui qui a longtemps cherch� sans trouver.(Bachelard)
    La connaissance s'acquiert par l'exp�rience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2006
    Messages
    12 860
    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 860
    Billets dans le blog
    1
    Par d�faut
    Citation Envoy� par fred1599 Voir le message
    Pour obtenir le r�sultat que tu veux, il ne faut en r�alit� cr�er qu'une seule et unique compr�hension.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    dd = {k: {"data": tuple(range(k+1))} for k in range(1, 6)}
    Joli
    Effectivement mettre la compr�hension dans le dictionnaire "parent" la rend visible de l'enfant.

    Citation Envoy� par fred1599 Voir le message
    La compr�hension interne cr�e sa propre "bulle" (sa propre port�e).
    Oui c'est en effet ce que j'ai compris apr�s coup, comme je l'ai dit. Apr�s il y a aussi l'histoire du double tuple de mon PS pour lequel j'ai encore du mal � voir comment �a se raccorde avec le reste de l'histoire mais bon, c'est pas super important (je fais rarement du tuple de tuple)

    Citation Envoy� par fred1599 Voir le message
    Je pense que ta source d'erreur est le fait d'avoir d�j� fait du python 2.x
    Oui c'est probable. Merci de ton aide
    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]

  4. #4
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 259
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 259
    Par d�faut
    Hello

    Pour le tuple c'est m�me tarif,

    1. Il y a une compr�hension de dictionnaire externe : {k: ... for k in range(1, 6)}. Elle d�finit une variable k dans sa bulle.
    2. � l'int�rieur, pour la valeur, il y a un g�n�rateur interne : (... for k in range(1, 6)). �a cr�e une autre variable k qui n'existe que dans sa propre bulle.


    ----

    Pourquoi je dis que �a peut venir de python 2.x ? C'est tout simplement parce-que cette fuite de variable existait... Guido van Rossum a lui-m�me qualifi� ce comportement d'artefact d'impl�mentation et de "vilain petit secret" de Python

    Source

    Pour exemple simple,

    En python 2.7

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    fred@FredDebian:~$ python2
     Python 2.7.18 (default, Mar  9 2025, 16:24:14) 
    [GCC 12.2.0] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = 'avant'
    >>> a = [x for x in range(3)]
    >>> print x
    2
    �a aurait d� afficher 'avant' !
    Ce comportement �tait une source de bogues subtils, car il pouvait �craser involontairement des variables existantes dans la port�e englobante. Ceci a �t� corrig� dans la version 3.

    En python 3.13

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    fred@FredDebian:~$ python3.13
    Python 3.13.5 (main, Jun 25 2025, 18:55:22) [GCC 14.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = 'avant'
    >>> a = [x for x in range(3)]
    >>> print(x)
    avant
    Celui qui trouve sans chercher est celui qui a longtemps cherch� sans trouver.(Bachelard)
    La connaissance s'acquiert par l'exp�rience, tout le reste n'est que de l'information.(Einstein)

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [eZ Publish] CSS et JS ne marchent pas pour le back-office
    Par V4Vendetta dans le forum EDI, CMS, Outils, Scripts et API
    R�ponses: 2
    Dernier message: 02/04/2012, 10h01
  2. Ma requ�te ne calcul pas pour tout les champs
    Par leloup84 dans le forum Requ�tes
    R�ponses: 10
    Dernier message: 01/03/2006, 12h59
  3. Ma requ�te ne calcul pas pour tout les champs
    Par leloup84 dans le forum Langage SQL
    R�ponses: 2
    Dernier message: 01/03/2006, 10h11
  4. [Performance] - Blob ou pas pour les images d'un site ?
    Par ShinJava dans le forum SQL Proc�dural
    R�ponses: 2
    Dernier message: 04/07/2005, 17h32
  5. [VB.NET] Les évènements ne marchent pas
    Par Dnx dans le forum ASP.NET
    R�ponses: 6
    Dernier message: 28/01/2005, 12h54

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