Impression d'une chaine de caractère en utilisant un dictionnaire pour le format
Fermé
getudir78
Messages postés
28
Date d'inscription
vendredi 3 janvier 2014
Statut
Membre
Dernière intervention
2 septembre 2020
-
Modifié le 9 déc. 2019 à 00:11
trifou - 11 déc. 2019 à 18:51
trifou - 11 déc. 2019 à 18:51
A voir également:
- Replacement index 1 out of range for positional args tuple
- Spouleur d'impression - Guide
- Caractère ascii - Guide
- Formate pour taxer client frigo vide ✓ - Forum Vos droits sur internet
- Format epub - Guide
- Télécharger dictionnaire larousse pdf gratuit - Télécharger - Dictionnaires & Langues
1 réponse
Bonjour,
Cela vient du fait que les keys du dict sont numériques, format n'accepte pas cela pour un dict.
Donc il faudrait faire pour au départ une simple liste
La même chose pour le dict
On pourrait croire que ça fonctionne comme on veut, sauf que non, car les dict sont par nature non ordonné.
Donc il faut trier pour obtenir la même chose que la liste de départ
Conclusion :
Il est préférable de ne pas utiliser de clef numérique pour les dict surtout si on a besoin de l'afficher avec format ^^
Cela vient du fait que les keys du dict sont numériques, format n'accepte pas cela pour un dict.
Donc il faudrait faire pour au départ une simple liste
s = '{1} {0} {2} {4} {3}' digits = ['zéro', 'un', 'deux', 'trois', 'quatre'] print('Format list', s) print(s.format(*digits))
La même chose pour le dict
dic = {i:v for i, v in enumerate(digits)} print('Format dict', s) print(s.format(*dic.values()))
On pourrait croire que ça fonctionne comme on veut, sauf que non, car les dict sont par nature non ordonné.
dic = {i:v for i, v in enumerate(digits[1:], 1)} dic[0] = digits[0] print(s.format(*dic.values()))
Donc il faut trier pour obtenir la même chose que la liste de départ
print(s.format(*(dic[i] for i in sorted(dic))))
Conclusion :
Il est préférable de ne pas utiliser de clef numérique pour les dict surtout si on a besoin de l'afficher avec format ^^
9 déc. 2019 à 15:14
Merci pour ton analyse détaillée qui m’a permis d’y voir clair et de résoudre mon problème d’impression. Pour faire le point, si j’ai bien compris :
- 1 - quand on crée un dictionnaire, l’ordre des clés utilisées pour sa construction se retrouve dans le dictionnaire qui en est le reflet. A sa création, le dictionnaire est alors ordonné et le restera si on ne le modifie pas
- 2 - quand on rajoute un nouvel item au dictionnaire, l’ordre n’est plus certain et il faut alors ordonner les clés par une fonction anonyme, pour retrouver l’ordre souhaité.
- 3 - *dictionnaire donne à toutes les clés du dictionnaire et *dictionnaire.values() parcourt les valeurs correspondantes.
-
Peux-tu me confirmer qu’il en est bien ainsi ?
Il reste un point mystérieux concernant les ** appliquées à des dictionnaires: Les clés du dictionnaire que j’ai créé, ne sont pas des entiers mais des strings d’entiers ; par exemple la clé d’indice 0 n’est pas 0 mais ‘0’, qui est donc un caractère.
Néanmoins, **dictionnaire crée une erreur d’indice ; :
IndexError: Replacement index 1 out of range for positional args tuple
Puisque les clés ne sont pas des entiers, d’où provient cette erreur ?
L’essentiel, c’est que maintenant, je dispose d une solution claire et viable pour imprimer du texte avec un format utilisant un dictionnaire.
Sois-en encore remercié.
Tous mes remerciements également à « Comment ça marche » pour ce remarquable forum.
Cordialement
9 déc. 2019 à 16:53
Si on souhaite toujours avoir un dict ordonné par clés, il faut se tourner vers la classe OrderedDict du module collections.
Oui c'est ça pour *dictionnaire, c'est un raccourci de *dictionnaire.keys()
Puisque les clés ne sont pas des entiers, d’où provient cette erreur ?
En fait, ce n'est pas spécifique aux entiers, mais à toute clé de dictionnaire non conforme, elle doit avoir les mêmes règles d'écriture que la déclaration d'une variable typique pour pouvoir être utilisée avec format.
https://docs.python.org/3/library/string.html#format-string-syntax
... it is not possible to specify arbitrary dictionary keys (e.g., the strings '10' or ':-]') within a format string.
C'est pareil aux règles des arguments nommés des fonctions finalement.
10 déc. 2019 à 21:15
Merci pour toutes ces infos précises.
Je ne vais pas trop dans la doc de Python parce qu'elle n'est pas toujours simple à comprendre Je devrais néanmoins m'y plonger dans l'espoir que ça finira par s'éclaircir.
Comme je travaille avec Python 3.8, je bénéficie des propriétés d'ordre des dictionnaires qui sont nouvelles, ce dont je n'avais pas conscience; mais c'est dangereux car si mon modeste code s'exécute sur une version antérieure, ça ne fonctionnera plus.
La doc est sans appel, ** ne peut pas s'appliquer au dictionnaire que j'ai créé, à cause des clés du type {'entier'}
En ce qui concerne les impressions de chaînes de caractères utilisant .format(), j'ai finalement trouvé un raccourci très simple :
"chaîne de caractère".format(*liste ).
Pour les exemples que tu proposes, ça serait
print(s.format(*digits))
et pour les impressions de mon programme test, ça donnerait
print(Texte_pour_impression.format(*liste_ville)).
C'est plus simple que de construire un dictionnaire, mais je ne sais pas ce que ça donne avec les versions antérieures de Python.
Que penses-tu de ce raccourci pour créer les bons arguments à .format() ?
Cordialement,
11 déc. 2019 à 18:51
Tout dépend du contexte du code, on n'a généralement pas besoin de formater une chaîne avec format pour qu'elle soit compatible à la fois avec différents types de structures en paramètres, et généralement on utilise autre chose comme clés d'un dictionnaire que de simples numériques. Même si on peut le faire, on aura sans doute jamais besoin de passer un dictionnaire de ce type directement à format.