J'ai le json dans le format suivant:
# Called by get_system_state(myDict, 1)
Je stocke ceci dans un dictionnaire et je dois effectuer un traitement à ce sujet.
Pour un "Tid ", Je veux pouvoir renvoyer la valeur" @default "dans la partie" status ". Par exemple, si je demande "Tid" = 1, je devrais obtenir la sortie suivante.
SORTIE ATTENDUE:
def get_system_state(myDict, id):
for i in ["id", "@default"]:
print (myDict.get(i))
if any(c == id_type for c in myDict.values()):
yield {i: myDict.get(i) for i in ["id", "@default"]}
else:
for i in myDict.values():
if isinstance(i, dict):
yield from get_system_state(i, id_type)
J'ai la méthode suivante pour le moment, mais cela me renvoie ceci et je ne comprends pas pourquoi.
{ "Tid": null,
"status": null
}
Ma méthode:
{ "Tid": "1",
"status": "0" -->this is the value from the @default attribute
}
# note that the "status" value is the attribute @default.
myDict =
{
"Garden": {
"GroundFloor": {
"@loc": "porch",
"@myID": "35C",
"Tid": "1",
"InfoList": {
"status": {
"@default": "0",
"@myID": "20C"
},
"count": {
"@default": "0",
"@myID": "1"
}
}
},
"TopFloor": {
"@loc": "backyard",
"@myID": "35C",
"Tid": "2",
"InfoList": {
"status": {
"@default": "0",
"@myID": "20D"
},
"count": {
"@default": "0",
"@myID": "2"
}
}
}
},
"BackYard": {
"GroundFloor": {
"@loc": "porch",
"@myID": "35C",
"Tid": "3",
"InfoList": {
"status": {
"@default": "0",
"@myID": "20C"
},
"count": {
"@default": "0",
"@myID": "1"
}
}
},
"TopFloor": {
"@loc": "backyard",
"@myID": "35C",
"Tid": "4",
"InfoList": {
"status": {
"@default": "0",
"@myID": "20D"
},
"count": {
"@default": "0",
"@myID": "2"
}
}
}
},
... many more nested layers...
}
3 Réponses :
Je viens de changer votre dictionnaire O/P: si vous passez O/P: Update: si un dictionnaire n'a pas le "Jardin" comme dictionnaire de premier niveau "Tid": "2", "InfoList": {"status": {"@default": "1", "@ myID": "20D"}, code> @ valeur par défaut à des fins de test.
def get_system_state(myDict, id):
for k1,v1 in myDict.items():
for k,v in v1.items():
for x in v:
if 'Tid' in v and v['Tid'] is not None and v['Tid'].isdigit() and int(v['Tid']) == id:
return [{'Tid':id,'status':v['InfoList']['status']['@default']}]
[{'Tid': 2, 'status': '1'}]
id=2new_dict = get_system_state(myDict, 2)
[{'Tid': 1, 'status': '0'}]
myDict ={
"Garden": {
"GroundFloor": {
"@loc": "porch",
"@myID": "35C",
"Tid": "1",
"InfoList": {"status": { "@default": "0","@myID": "20C"},
"count": {"@default": "0","@myID": "1"}
}
},
"TopFloor": {
"@loc": "backyard",
"@myID": "35C",
"Tid": "2",
"InfoList": { "status": { "@default": "1","@myID": "20D"},
"count": {"@default": "0","@myID": "2" }
}
}
}
}
def get_system_state(myDict, id):
for k,v in myDict['Garden'].items():
for x in v:
if 'Tid' in v and v['Tid'] is not None and v['Tid'].isdigit() and int(v['Tid']) == id:
return [{'Tid':id,'status':v['InfoList']['status']['@default']}]
new_dict = get_system_state(myDict, 1)
print(new_dict)
Par exemple, si le dictionnaire n'a pas la chaîne "Garden" comme nœud de niveau supérieur, comment puis-je le rendre générique dans tous les cas?
J'ai mis à jour myDict dans la question pour refléter ce que je veux dire.
@LauraSmith Essayez maintenant.
Une dernière question, est-il possible que le return {'Tid': id, 'status': v ['InfoList'] ['status'] ['@ default']} renvoie une liste au lieu?
J'ai essayé cette liste de retour ({'Tid': id, 'status': v ['InfoList'] ['status'] ['@ default']} ) . Cela me donne une erreur L'objet 'NoneType' n'est pas itérable .
@Laura Smith signifie comme ceci [{'Tid': 2, 'status': '1'}] ou [2,0]
comme le [{'Tid': 2, 'status': '1'}] car je veux l'envoyer à la méthode jsonify . C'est pourquoi je veux retourner une liste et faire quelque chose comme ça si possible, jsonify (key_list sinon key_list sinon key_list [0]) .
@LauraSmith signifie que je n'obtiens aucune erreur. Réponse mise à jour
Essayez d'utiliser ceci:
def get_system_state(myDict, id):
garden_details = myDict.get("Garden", None)
if garden_details:
for floor in garden_details:
Tid = garden_details[floor].get(str("Tid"), None)
if Tid == str(id):
return {'Tid': Tid, 'status': garden_details[floor]['InfoList']['status']['@default']}
Vérifiez si cela fonctionne pour vous.
Je veux le rendre plus générique plutôt que d'utiliser la chaîne "Garden". Je mets à jour myDict pour le montrer.
garden_details = list (myDict.values ()) [0] utilisez ceci au lieu de garden_details = myDict.get ("Garden", None) si la position est fixe.
Vous pouvez utiliser une récursion simple:
[{'Tid': '1', 'status': '0'}]
Sortie:
data = {'Garden': {'GroundFloor': {'@loc': 'porch', '@myID': '35C', 'Tid': '1', 'InfoList': {'status': {'@default': '0', '@myID': '20C'}, 'count': {'@default': '0', '@myID': '1'}}}, 'TopFloor': {'@loc': 'backyard', '@myID': '35C', 'Tid': '2', 'InfoList': {'status': {'@default': '0', '@myID': '20D'}, 'count': {'@default': '0', '@myID': '2'}}}}, 'BackYard': {'GroundFloor': {'@loc': 'porch', '@myID': '35C', 'Tid': '3', 'InfoList': {'status': {'@default': '0', '@myID': '20C'}, 'count': {'@default': '0', '@myID': '1'}}}, 'TopFloor': {'@loc': 'backyard', '@myID': '35C', 'Tid': '4', 'InfoList': {'status': {'@default': '0', '@myID': '20D'}, 'count': {'@default': '0', '@myID': '2'}}}}}
def get_id(d, id):
if isinstance(d, dict) and d.get('Tid') == id:
yield {'Tid':d['Tid'], 'status':d['InfoList']['status']['@default']}
for i in getattr(d, 'values', lambda :[])():
yield from get_id(i, id)
print(list(get_id(data, '1')))
TopFloor "vous manquez le devisAccédez à ce site Web et validez le json - https://jsonlint.com/
@Nitin l'a validé et mis à jour.
@LauraSmith Permettez-moi de vérifier pourquoi cela se produit. Je reviendrai vers toi
@LauraSmith Quel est votre résultat attendu?
@bharatk Je l'ai mis à jour dans le code. Il est étiqueté SORTIE ATTENDUE.
@LauraSmith qu'en est-il du reste d'une partie du dictionnaire si une condition est une correspondance, ou si vous voulez simplement ajouter
statuscomme clé et@defaultest une valeur en dehors du dictionnaire imbriqué si la condition correspondJe veux pouvoir renvoyer le résultat avec le "Tid" et sa valeur et le "status" et sa valeur qui est le @default lorsque j'interroge pour un "Tid" spécifique dans la méthode get_system_state. À cette méthode, je passe le myDict et l'id.