Le dictionnaire Python et le format JSON partagent une syntaxe presque identique : des paires clé-valeur séparées par des virgules, encadrées par des accolades. Cette proximité structurelle explique pourquoi le dic Python est le point d’entrée naturel vers JSON. Le module json de la bibliothèque standard convertit un dict en chaîne JSON (et inversement) en une seule ligne de code, sans dépendance externe.
La correspondance n’est pas qu’esthétique. Les types natifs du dictionnaire (chaînes, entiers, flottants, booléens, listes, None) se traduisent directement en types JSON valides. Cette conversion quasi transparente a fait du couple dict/json le socle de la plupart des échanges de données en Python, des appels API REST aux fichiers de configuration.
Garantie d’ordre d’insertion dans un dic Python depuis la version 3.7
Avant Python 3.6, l’ordre des clés dans un dictionnaire n’était pas garanti. Un dict pouvait restituer ses paires dans un ordre différent de celui dans lequel elles avaient été ajoutées. Depuis Python 3.7, l’ordre d’insertion est une garantie officielle du langage, et non plus un simple détail d’implémentation CPython.
Cette garantie change la donne pour le travail avec JSON. Quand vous sérialisez un dict avec json.dumps, l’ordre des clés dans la sortie JSON reflète l’ordre d’insertion dans le dictionnaire source. Pour des pipelines de tests automatisés ou des systèmes de cache, cette stabilité évite les faux positifs lors de comparaisons de fichiers.
Si vous avez besoin d’un ordre alphabétique plutôt que chronologique, le paramètre sort_keys=True de json.dumps trie les clés avant sérialisation. Cette option produit une sortie déterministe, utile pour générer des diff lisibles ou stocker des configurations versionnées dans Git.

Conversion dict vers JSON : dumps, dump et leurs différences
Le module json propose deux fonctions de sérialisation qui portent à confusion chez les débutants.
json.dumps(objet)renvoie une chaîne de caractères JSON. Le « s » final signifie « string ». C’est la fonction à utiliser quand vous transmettez des données en mémoire, par exemple dans le corps d’une requête HTTP.json.dump(objet, fichier)écrit directement dans un fichier ouvert en écriture. Elle évite de stocker la totalité de la chaîne en mémoire avant l’écriture, ce qui compte pour les gros volumes de données.- Le paramètre
ensure_ascii=Falsepréserve les caractères UTF-8 (accents, idéogrammes) au lieu de les convertir en séquences d’échappement\uXXXX. Combiné avecencoding='utf-8'à l’ouverture du fichier, il produit un JSON lisible par un humain francophone.
La symétrie existe côté lecture : json.loads parse une chaîne, json.load lit un objet fichier. Chaque fonction a un rôle précis selon la source de données (chaîne en mémoire ou fichier sur disque).
Tri et réorganisation d’un dic Python pour une sortie JSON stable
Trier un dictionnaire en Python ne fonctionne pas comme trier une liste. sorted(d) renvoie une liste de clés, pas un dictionnaire. Pour obtenir un dict réordonné, il faut reconstruire un nouveau dictionnaire à partir des paires triées :
dict_trie = dict(sorted(mon_dict.items()))
Cette reconstruction crée un nouveau dict dont l’ordre d’insertion correspond à l’ordre alphabétique des clés. Sérialisé ensuite avec json.dumps, il produit un JSON aux clés ordonnées sans recourir à sort_keys=True.
Tri par valeur ou par clé imbriquée
Le tri par valeur utilise une fonction lambda comme argument key de sorted. Pour un dictionnaire dont les valeurs sont elles-mêmes des dictionnaires (structure courante en JSON), vous pouvez trier sur n’importe quel champ imbriqué.
En revanche, sort_keys=True dans json.dumps ne trie que les clés, pas les valeurs. Si vos données JSON contiennent des listes, l’ordre des éléments dans ces listes reste inchangé. C’est une limite à connaître : la normalisation d’une sortie JSON complexe demande un traitement en amont, côté Python, avant la sérialisation.

Sécurité et limites du module json avec des données externes
Le module json de la bibliothèque standard est considéré comme sûr face aux attaques par injection, contrairement à eval() ou à la désérialisation via pickle. Le parser JSON de Python refuse tout ce qui n’est pas du JSON valide : pas d’exécution de code, pas d’instanciation d’objets arbitraires.
Cette sécurité a des contreparties. Le module json ne gère nativement que les types de base (dict, list, str, int, float, bool, None). Un objet datetime, un set ou une instance de classe personnalisée provoquent une TypeError à la sérialisation. Deux approches existent :
- Passer un paramètre
defaultàjson.dumpsavec une fonction qui convertit les types non standard en types sérialisables (par exemple, convertir undatetimeen chaîne ISO 8601). - Créer une sous-classe de
json.JSONEncoderet surcharger la méthodedefault, solution plus structurée pour les projets qui manipulent régulièrement des types personnalisés. - Pour la lecture, le paramètre
object_hookdejson.loadspermet de transformer chaque objet JSON en un type Python personnalisé au moment du parsing.
Taille des fichiers et performance
Pour des fichiers JSON de plusieurs centaines de mégaoctets, le module standard charge tout en mémoire d’un coup. Des bibliothèques tierces comme ijson offrent un parsing incrémental (streaming), mais elles sortent du périmètre du dict classique. Le choix entre json standard et parser streaming dépend du volume de données.
Le couple dic Python et module json couvre la grande majorité des cas d’usage courants : lecture de fichiers de configuration, consommation d’API REST, échange de données entre microservices. Les limites apparaissent aux extrêmes, sur les très gros volumes ou les types non standard, et des solutions documentées existent pour chaque cas. La vraie force de ce duo reste sa présence dans la bibliothèque standard : aucune installation, aucune dépendance, un import et le travail commence.

