Hilfe bei JSON und Dictionary

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
opccorsa
User
Beiträge: 34
Registriert: Samstag 20. Juli 2013, 07:43

Hallo Leute, ich melde mich mal wieder seit langer Zeit hier im Forum mit einem Problem.
Ich habe eine JSON Datei wo ich mehrere Dict und Lists habe. Das einlesen und schreiben ist kein Problem. Leider komme ich nicht an die einzelnen Werte der JSON Datei. Ich habe es versucht mit parsen, rekursive und aktuell mit Ebenen. Ich bekomme im Moment ein Dictionary. Dieses bekomme ich auch nicht getrennt. Ziel des Ganzen wäre es z.B. einen String (conveyer__ip) bzw (conveyer__shuttle1__net_port) zu haben und das dazugehörige Value (12345) bzw. (13000). Ich hoffe ihr könnte mir ein wenig auf die Sprünge helfen.
LG :)

Code: Alles auswählen

#!/usr/bin/env python3
# coding: utf-8

import json

with open('data.json', 'r') as f:
    data = json.load(f)

def flatten_json(y):
    out = {}
    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + '_')
                i += 1
        else:
            out[name[:-1]] = x
    flatten(y)
    return out

test = flatten_json(data)
print(test,sep=",")
print(test.get("conveyer1__shuttle1__net_port"))

Code: Alles auswählen

{'conveyer1__shuttle1__net_port': '13000', 'conveyer1__shuttle1__track1__right__node1_type': 'can', 'conveyer1__shuttle1__track1__right__node1_port': '0', 'conveyer1__shuttle1__track1__right__node1_id': '20', 'conveyer1__shuttle1__track1__right__node1_io1__dir': '1', 'conveyer1__shuttle1__track1__right__node1_io1__type': 'Stopper', 'conveyer1__shuttle1__track1__right__node1_io2__dir': '0', 'conveyer1__shuttle1__track1__right__node1_io2__type': 'Stopini', 'conveyer1__shuttle1__track1__right__node1_io3__dir': None, 'conveyer1__shuttle1__track1__right__node1_io3__type': None, 'conveyer1__shuttle1__track1__right__node1_io4__dir': None, 'conveyer1__shuttle1__track1__right__node1_io4__type': None}
13000

Code: Alles auswählen

{
	"conveyer1": [{
		"ip": "12345",
		"shuttle1": [{
			"net_port": "13000",
			"track1": [{
				"right": [{
					"node1": {
						"type": "can",
						"port": "0",
						"id": "20",
						"io1": [{
							"dir": "1",
							"type": "Stopper"
						}],
						"io2": [{
							"dir": "0",
							"type": "Stopini"
						}],
						"io3": [{
							"dir": null,
							"type": null
						}],
						"io4": [{
							"dir": null,
							"type": null
						}],
						"motor1": [{
							"dir": {},
							"mode": {},
							"speed": {},
							"acc": {}
						}]
					}
				}],
				"left": [{
					"node1": {
						"type": {},
						"port": {},
						"id": {},
						"io1": [{
							"dir": {},
							"type": {}
						}],
						"io2": [{
							"dir": {},
							"type": {}
						}],
						"io3": [{
							"dir": {},
							"type": {}
						}],
						"io4": [{
							"dir": {},
							"type": {}
						}],
						"motor2": [{
							"dir": {},
							"mode": {},
							"speed": {},
							"acc": {}
						}]
					}
				}]
			}]
		}]
	}]
}
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@opccorsa: Sag mal kann das sein das alle Arrays in diesem JSON-Objekt immer genau *ein* JSON-Objekt enthalten‽ Wie sinnlos ist das denn? Also kann man die Listen einfach ignorieren. Wäre auch sonst interessant was da sonst passieren sollte.

Statt ``type(x) is SomeType`` würde man besser ``isinstance(x, SomeType)`` schreiben. Dann funktioniert das zum Beispiel auch noch wenn man da statt `dict` `OrderedDict` bekommen würde.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Code: Alles auswählen

#!/usr/bin/env python3
import json
from functools import singledispatch
from pprint import pprint


@singledispatch
def visit(node, path):
    raise ValueError(repr(node))


@visit.register(type(None))
@visit.register(str)
def visit_simple_type(node, path):
    yield "_".join(path), node


@visit.register(dict)
def visit_object(node, path):
    for name, value in node.items():
        yield from visit(value, path + [name])


@visit.register(list)
def visit_array(node, path):
    if len(node) != 1:
        raise ValueError(f"unexpected length {len(node)} ({node!r})")
    yield from visit(node[0], path)


def flatten(data):
    return dict(visit(data, []))


def main():
    with open("test.json", "rb") as file:
        data = json.load(file)
    pprint(flatten(data))


if __name__ == "__main__":
    main()
Ausgabe für die Beispieldatei:

Code: Alles auswählen

{'conveyer1_ip': '12345',
 'conveyer1_shuttle1_net_port': '13000',
 'conveyer1_shuttle1_track1_right_node1_id': '20',
 'conveyer1_shuttle1_track1_right_node1_io1_dir': '1',
 'conveyer1_shuttle1_track1_right_node1_io1_type': 'Stopper',
 'conveyer1_shuttle1_track1_right_node1_io2_dir': '0',
 'conveyer1_shuttle1_track1_right_node1_io2_type': 'Stopini',
 'conveyer1_shuttle1_track1_right_node1_io3_dir': None,
 'conveyer1_shuttle1_track1_right_node1_io3_type': None,
 'conveyer1_shuttle1_track1_right_node1_io4_dir': None,
 'conveyer1_shuttle1_track1_right_node1_io4_type': None,
 'conveyer1_shuttle1_track1_right_node1_port': '0',
 'conveyer1_shuttle1_track1_right_node1_type': 'can'}
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten