J'ai un objet dict avec ce type de structure
x = {"a": '{"b": "c"}'}
val = "d"
magic(x, val)
>>> {"a": '{"b": "d"}'}
Je voudrais utiliser une boucle pour insérer différentes valeurs dans la zone "c" pour utiliser ailleurs dans un projet. Le problème est que les guillemets simples autour du b et du c rendent cela plus difficile.
J'ai essayé:
{"a": '{"b": "{}"}'.format("d")}
Mais cela renvoie le dict sans évaluer le fonction de format.
J'ai aussi essayé:
{"a": '{"b": "{}"}.format("d")'}
Mais cela renvoie une erreur. J'ai parcouru 2 heures de combinaisons et de questions SO comme ( ceci , ceci et this ) mais j'ai réalisé que j'avais besoin de l'aide de quelqu'un qui sait quoi ils font.
Une solution viable ressemblerait à:
{"a": '{"b": "c"}'}
Remarque: Aux commentaires demandant "pourquoi ce format"? Je ne crée pas ces objets et donc ils ne sont pas mon choix. J'ai une API à laquelle je me suis connecté. Je récupère les données actuelles, je les modifie et je les télécharge à nouveau. Il n'y a aucune possibilité de "ne pas utiliser de chaîne littérale". C'est ce à quoi s'attend la publication de l'API. Je ne suis pas en mesure pour le moment de demander aux responsables de changer leur système de stockage
4 Réponses :
Cela devrait fonctionner pour vous
import json
obj = {"a": '{"b": "c"}'}
inner_a = json.loads(obj['a'])
inner_a['b'] = 'd'
obj['a'] = json.dumps(inner_a)
Essayez ceci:
{"a": '{"b": "d"}'}
Et maintenant:
print(x)
Est:
import ast
x = {"a": '{"b": "c"}'}
a = ast.literal_eval(x['a'])
a['b'] = 'd'
x['a'] = str(a)
Cela fonctionne pour le problème considérablement simplifié de l'OP (je suppose), mais je parie que cela ne serait utile pour rien d'autre. Que diriez-vous de {"a": '{"c": "c"}'} ?
Mon point est que OP traite clairement des chaînes json, donc utiliser autre chose que json pour le manipuler semble inutile
@RobinNemeth a raison, c'est une solution intéressante mais ne résout pas le problème présenté. Comme vu dans l'exemple, "c", ou plus largement, la valeur d'origine n'est pas une entrée dans la fonction magic . Ceci est important car la valeur sera inconnue lors du remplacement
@RobinNemeth a édité le mien.
@PierreLafortune a édité le mien.
Vous essayez de construire un littéral de chaîne, alors qu'il serait plus facile de simplement construire un dict directement; il n'est pas nécessaire que les valeurs d'un dict littéral soient elles-mêmes des littéraux. Le problème est que la valeur de d ['a'] est une chaîne plutôt qu'un dict. Est-ce vraiment nécessaire? Pour un dictionnaire simple, vous pouvez simplement utiliser:
>>> import json
>>> def smagic(d, val):
... inner = json.loads(d['a'])
... inner['b'] = val
... d['a'] = json.dumps(inner)
...
>>> my_dict = {"a": '{"b": "c"}'} # my_dict['a'] is a string
>>> smagic(my_dict, "Is this it?")
>>> my_dict
{'a': '{"b": "Is this it?"}'}
Lorsque la valeur est une chaîne, cependant, cela dépend beaucoup de son format. Si les clés sont toutes des chaînes et que les valeurs sont des chaînes ou des nombres, vous pouvez utiliser le module json pour le convertir en dict, opérer dessus et le replacer:
>>> def magic(d, val):
... d['a']['b'] = val
...
>>> my_dict = {"a": {"b": "c"}} # my_dict['a'] is also a dict
>>> magic(my_dict, 'd')
>>> my_dict
{'a': {'b': 'd'}}
>>> magic(my_dict, {'x': 1, 'y' :2, 'z': 3})
>>> my_dict
{'a': {'b': {'x': 1, 'y': 2, 'z': 3}}}
Vous pouvez étendre cette solution en utilisant repr et eval , mais je déconseillerais ce niveau de complexité à moins qu'il n'y ait aucun moyen de l'éviter.
#use this code according for reference
print("enter name\n")
n1=input("enter 1st name ")
ln=input("enter last name ")
add=input("enter address ")
dic={'name':{"1st name":n1,"lname":ln},'address':add}
print(dic.values())
print(dic)
Avez-vous essayé
eval?Pourquoi voulez-vous que vos valeurs soient une représentation de chaîne d'un dict plutôt qu'un dict?
Lorsque vous avez une valeur de chaîne, vous utilisez les guillemets autour, mais lorsque vous avez une valeur non-chaîne, il ne doit pas y avoir de guillemets. Ainsi, par exemple, une valeur entière est
{'a': 2}, et similaire si la valeur est un dict, vous ne devriez pas avoir de guillemets autour de la valeur, utilisez donc{'a' : {'b': 'c'}}.Aux commentaires demandant «pourquoi»? Je ne crée pas ces objets et donc ils ne sont pas mon choix. J'ai une API à laquelle je me suis connecté. Je récupère les données actuelles, je les modifie et je les télécharge à nouveau. Il n'y a aucune possibilité de "ne pas utiliser de chaîne littérale". C'est ce à quoi s'attend la publication de l'API. Je ne suis pas en mesure pour le moment de demander aux responsables de la maintenance de changer leur système de stockage