1075 votes

Convertir une représentation de type String d'un dictionnaire en un dictionnaire ?

Comment puis-je convertir le str représentation d'un dict comme la chaîne de caractères suivante, dans un dict ?

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"

Je préfère ne pas utiliser eval . Que puis-je utiliser d'autre ?

La raison principale est qu'une des classes de mes collègues qu'il a écrites, convertit toutes les entrées en chaînes de caractères. Je ne suis pas d'humeur à aller modifier ses classes pour résoudre ce problème.

1 votes

Si vous ne pouvez pas utiliser Python 2.6, vous pouvez utiliser une implémentation simple de safeeval telle que code.activestate.com/recipes/364469 Il s'appuie sur le compilateur Python pour vous éviter d'avoir à faire tout le travail brut vous-même.

22 votes

Note : Pour ceux qui viennent ici avec d'apparence faussement similaire JSON données, vous voulez aller lire Analyser JSON en Python à la place. JSON est pas la même chose que Python . Si vous avez " Si vos chaînes de caractères sont entourées de guillemets doubles, vous avez probablement des données JSON. Vous pouvez également rechercher null , true o false La syntaxe Python utilise None , True y False .

1577voto

Jacob Gabrielson Points 8800

Vous pouvez utiliser la fonction intégrée ast.literal_eval :

>>> import ast
>>> ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}")
{'muffin': 'lolz', 'foo': 'kitty'}

C'est plus sûr que d'utiliser eval . Comme le disent ses propres documents :

\>>> help(ast.literal\_eval)
Help on function literal\_eval in module ast:

literal\_eval(node\_or\_string)
    Safely evaluate an expression node or a string containing a Python
    expression.  The string or node provided may only consist of the following
    Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
    and None.

Par exemple :

>>> eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
  File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 208, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 206, in rmtree
    names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mongo'
>>> ast.literal_eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
    return _convert(node_or_string)
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

0 votes

Je dois ajouter que vous devez assainir la chaîne pour l'utiliser avec ast.literal_eval. (assurez-vous que les guillemets et les doubles guillemets dans la chaîne sont échappés).

0 votes

Je reçois cette erreur Je suis sur python 2.6 (x86) sur Windows 7 x64 Fichier " D:\Python26\lib\ast.py ", line 48, in literal_eval node_or_string = parse(node_or_string, mode='eval') File " D:\Python26\lib\ast.py ", line 36, in parse return compile(expr, filename, mode, PyCF_ONLY_AST) File "<unknown>", line 1 ^ SyntaxError : invalid syntax

1 votes

Qu'en est-il "dict(a=1)" des cordes de style ?

364voto

ir0x539 Points 91

https://docs.python.org/3.8/library/json.html

JSON peut résoudre ce problème, mais son décodeur exige des guillemets doubles autour des clés et des valeurs. Si vous n'avez pas l'esprit un hack de remplacement ...

import json
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
json_acceptable_string = s.replace("'", "\"")
d = json.loads(json_acceptable_string)
# d = {u'muffin': u'lolz', u'foo': u'kitty'}

REMARQUE : si vos clés ou vos valeurs comportent des guillemets simples, cette solution échouera en raison du remplacement incorrect des caractères. Cette solution n'est recommandée que si vous avez une forte aversion pour la solution eval.

En savoir plus sur la citation unique json : jQuery.parseJSON génère une erreur "Invalid JSON" en raison d'un guillemet unique échappé dans le JSON.

4 votes

Je cherchais cette solution. +1 pour informer que le décodeur veut des guillemets autour des clés et des valeurs.

4 votes

Un autre problème se pose pour "{0: 'Hello'}" .

4 votes

Cela échoue également si vous avez des virgules de fin (non conforme à JSON), par exemple : "{'muffin' : 'lolz', 'foo' : 'kitty',}"

223voto

tokhi Points 1911

En utilisant json.loads :

>>> import json
>>> h = '{"foo":"bar", "foo2":"bar2"}'
>>> d = json.loads(h)
>>> d
{u'foo': u'bar', u'foo2': u'bar2'}
>>> type(d)
<type 'dict'>

22 votes

Je ne pense pas que cela réponde à la question de l'OP. Comment utiliser json.laads pour convertir une chaîne s = "{muffin' : 'lolz', 'foo' : 'kitty'}" en dict ?

0 votes

Pourquoi est-ce que 'u' s'imprime dans la sortie ?? eg - str = '{"1" : "P", "2" : "N", "3" : "M"}' d = json.loads(str) print d la sortie est : {u'1' : u'P', u'3' : u'M', u'2' : u'N'}

4 votes

@technazi : json.loads(h.replace("", ""')))

25voto

Blixt Points 23266

Si la chaîne peut toujours de confiance, vous pouvez utiliser eval (ou utiliser literal_eval comme suggéré ; c'est sûr quelle que soit la chaîne de caractères). Sinon, vous avez besoin d'un analyseur syntaxique. Un analyseur JSON (tel que simplejson) pourrait fonctionner s'il ne stocke que le contenu qui correspond au schéma JSON.

9 votes

À partir de la version 2.6, simplejson est inclus dans la bibliothèque standard de Python en tant que module json.

12 votes

Oui, c'est une bonne réponse, mais notez qu'officiellement, JSON ne prend pas en charge les chaînes de caractères entre guillemets, comme le montre l'exemple de l'auteur de l'article.

20voto

Utilisez json . le ast La bibliothèque consomme beaucoup de mémoire et est plus lente. J'ai un processus qui doit lire un fichier texte de 156Mo. Ast avec un délai de 5 minutes pour le dictionnaire de conversion json et 1 minute en utilisant 60% de mémoire en moins !

15 votes

Mais a ses limites : essayez de convertir la chaîne "{'foo' : 'bar',}"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X