1

JSONファイルがあり、Pythonを使用してクエリを実行したいと思います。しかし、私は事前に変数のネストされた場所を知りません。たとえば、Pythonにロードされて「data」と呼ばれる以下のJSONオブジェクトをクエリするには、次のようにします。

data['experiments']['initial_ns']['icdat']

ただし、これは、変数が。の下にあるicdat変数が下にあることを知っていることを前提としています。残念ながら、私はこの情報を持っていません。また、JSON構造は将来変更される可能性があります。構造全体を明示的に指定せずにJSON文字列内の変数にアクセスするためのより単純な変数はありますか?initial_nsexperiments

ありがとう!!!

{
    "experiments": [
        {
            "management": {
                "events": [
                    {
                        "date": "19122", 
                        "timp": "TI3", 
                        "eve": "tage"
                    }
                ]
            }, 
            "initial_ns": {
                "icpcr": "MZ", 
                "icdat": "1922"
            }, 
            "observed": {
                "mdat": "19403", 
                "time_series": [
                    {
                        "date": "198423", 
                        "etac": "0"
                    }
                ], 
                "adat": "190218"
            }, 
            "local_name": "lhi", 
            "exname": "SE", 
            "exp_dur": "1"
        }
    ]
}
4

4 に答える 4

2

jsonpath モジュールを見てください。http://goessner.net/articles/JsonPath/ . 検索文字列 $..icdat がニーズに合うと思います。

于 2012-09-05T23:46:41.650 に答える
1

「……構造全体を明示的に指定せずに?

はい、多くの方法があります。残念ながら、探している答えが指定されていません。

「スキーマに関して一意」(私の用語) とは次のとおりです。たとえば、キー Foo.bar を持つ複数の Foo 辞書がある場合、それは依然として一意です。一意ではないのは、Foo.bar を持つ Foo オブジェクトと Baz.bar を持つ Baz オブジェクトがある場合です。 を検索すると、{... baz:...}さまざまな種類のオブジェクトが返されます。

キーがスキーマに関して一意である場合、ツリー全体を検索できます。後で使用するためにすべてのキーと値のペアをディクショナリにキャッシュすることで、これを高速化できます(したがって、データ構造全体を解析する必要があるため、オペレーションは O(1) の「インスタント」償却コストです!) . これは、オブジェクトのセットを返したい場合でも機能します: acache = collections.defaultdict(set)を使用し、項目を前処理してキャッシュする場合は do を使用しますcache[key].add(value)

キーがスキーマの観点から一意でない場合は、パスについて合理的な推測を行い、Hans Then の回答利用 JsonPath: https://stackoverflow.com/a/12291240/711085 (または、スキーマを変更します)

于 2012-09-06T00:44:23.723 に答える
0

findElementByID()XML DOMパーサーの場合と同様に、ネストされたコンテナーで特定のキーを再帰的に検索する関数を作成できます。

def find_key(json, key):
    if isinstance(json, dict):
        if key in json:
            yield json[key]
    if isinstance(json, (dict, list)):
        for value in (json.itervalues() if isinstance(json, dict) else json):
            if isinstance(value, (dict, list)):
                for item in find_key(value, key):
                    yield item

>>> next(items_by_key(data, "icdat"))
'1922'

同じキーがドキュメント内の複数の場所にある可能性があるため、これは実際にはジェネレータとして記述されています。結果を反復処理してすべての値を取得できます。最初の値が必要な場合(またはそれが唯一の値であることがわかっている場合)は、next()上記のようにその周りを使用します。必要に応じて、に変換することもできlist()ます。

于 2012-09-05T23:26:51.590 に答える
0

いいえ。形式を知っている必要があります。そうしないと、その中のすべてを手動でループする必要があります。

于 2012-09-05T23:34:06.563 に答える