programing

키로 특정 JSON 값을 찾는 방법

iphone6s 2023. 3. 8. 20:51
반응형

키로 특정 JSON 값을 찾는 방법

다음과 같은 JSON이 있습니다.

{
  "P1": "ss",
  "Id": 1234,
  "P2": {
      "P1": "cccc"
  },
  "P3": [
      {
          "P1": "aaa"
      }
  ]
}

어떻게 하면 다 찾을 수 있지?P1모든 JSON을 반복하지 않고의 가치

추신:P1JSON의 어디에나 있을 수 있습니다.

만약 방법이 없다면 JSON을 통해 반복하는 방법을 알려주시겠습니까?

가 다른 답변에서 말했듯이, 제 생각에는 모든 가치를 찾을 수 있는 방법은 없는 것 같습니다."P1"전체 구조에서 반복되지 않고 키를 누릅니다.하지만 JSON과 관련된 또 다른 질문에 대한 @Mike Brennan의 답변을 보면서 JSON에서 Unicode가 아닌 string objects를 얻는 방법을 알게 되었습니다.

기본적인 생각은,object_hook이 파라미터는 디코딩되는 내용을 감시하고 원하는 값을 확인하는 것만을 허용합니다.

주의: 이 방법은 JSON(컬리 괄호로 둘러싸인 것)일 경우에만 작동합니다. {})를 참조해 주세요.

from __future__ import print_function
import json

def find_values(id, json_repr):
    results = []

    def _decode_dict(a_dict):
        try:
            results.append(a_dict[id])
        except KeyError:
            pass
        return a_dict

    json.loads(json_repr, object_hook=_decode_dict) # Return value ignored.
    return results

json_repr = '{"P1": "ss", "Id": 1234, "P2": {"P1": "cccc"}, "P3": [{"P1": "aaa"}]}'
print(find_values('P1', json_repr))

(Python 3) 출력:

['cccc', 'aaa', 'ss']

요전에도 같은 문제가 있었습니다.나는 결국 전체 대상을 뒤지고 목록과 받아쓰기를 모두 계산하게 되었다.다음 스니펫을 사용하면 여러 키의 첫 번째 항목을 검색할 수 있습니다.

import json

def deep_search(needles, haystack):
    found = {}
    if type(needles) != type([]):
        needles = [needles]

    if type(haystack) == type(dict()):
        for needle in needles:
            if needle in haystack.keys():
                found[needle] = haystack[needle]
            elif len(haystack.keys()) > 0:
                for key in haystack.keys():
                    result = deep_search(needle, haystack[key])
                    if result:
                        for k, v in result.items():
                            found[k] = v
    elif type(haystack) == type([]):
        for node in haystack:
            result = deep_search(needles, node)
            if result:
                for k, v in result.items():
                    found[k] = v
    return found

deep_search(["P1", "P3"], json.loads(json_string))

검색된 키가 포함된 dict가 반환됩니다.Haystack은 이미 Python 오브젝트이기 때문에 deep_search에 전달하기 전에 json.loads를 수행해야 합니다.

최적화에 관한 코멘트는 모두 환영합니다!

이 문제에 대한 나의 접근법은 다를 것이다.

JSON은 깊이 우선 검색을 허용하지 않으므로, json을 Python 개체로 변환하고 XML 디코더에 공급한 다음 검색하려는 노드를 추출합니다.

from xml.dom.minidom import parseString
import json        
def bar(somejson, key):
    def val(node):
        # Searches for the next Element Node containing Value
        e = node.nextSibling
        while e and e.nodeType != e.ELEMENT_NODE:
            e = e.nextSibling
        return (e.getElementsByTagName('string')[0].firstChild.nodeValue if e 
                else None)
    # parse the JSON as XML
    foo_dom = parseString(xmlrpclib.dumps((json.loads(somejson),)))
    # and then search all the name tags which are P1's
    # and use the val user function to get the value
    return [val(node) for node in foo_dom.getElementsByTagName('name') 
            if node.firstChild.nodeValue in key]

bar(foo, 'P1')
[u'cccc', u'aaa', u'ss']
bar(foo, ('P1','P2'))
[u'cccc', u'cccc', u'aaa', u'ss']

사용.jsonjson을 Python 객체로 변환한 후 재귀적으로 통과하는 것이 가장 효과적입니다.에는 목록 검토가 포함되어 있습니다.

import json
def get_all(myjson, key):
    if type(myjson) == str:
        myjson = json.loads(myjson)
    if type(myjson) is dict:
        for jsonkey in myjson:
            if type(myjson[jsonkey]) in (list, dict):
                get_all(myjson[jsonkey], key)
            elif jsonkey == key:
                print myjson[jsonkey]
    elif type(myjson) is list:
        for item in myjson:
            if type(item) in (list, dict):
                get_all(item, key)

JSON을 Python으로 변환하고 재귀적으로 검색하는 것이 가장 쉽습니다.

def findall(v, k):
  if type(v) == type({}):
     for k1 in v:
         if k1 == k:
            print v[k1]
         findall(v[k1], k)

findall(json.loads(a), 'P1')

(a는 문자열입니다)

예제 코드는 배열을 무시합니다.그것을 추가하는 것은 연습으로 남는다.

json은 단순한 문자열이라는 점에 유의하여 미리 보기 및 뒤 보기로 정규 표현을 사용하면 이 작업을 매우 빠르게 수행할 수 있습니다.

일반적으로 json은 요청에서 외부 api로 추출되기 때문에 어떻게 동작하는지를 나타내는 코드가 포함되어 있지만 코멘트가 되어 있습니다.

import re
#import requests
#import json

#r1 = requests.get( ... url to some api ...)
#JSON = str(json.loads(r1.text))
JSON = """
 {
  "P1": "ss",
  "Id": 1234,
  "P2": {
      "P1": "cccc"
  },
  "P3": [
     {
          "P1": "aaa"
     }
  ]
 }
"""
rex1  = re.compile('(?<=\"P1\": \")[a-zA-Z_\- ]+(?=\")')
rex2 = rex1.findall(JSON)  
print(rex2)

#['ss', 'cccc', 'aaa']

구조 전체에 걸쳐 반복하지 않고 P1과 관련된 모든 값을 찾을 수 있는 방법은 없다고 생각합니다.먼저 JSON 개체를 동등한 Python 개체로 역직렬화하는 재귀적인 방법을 소개합니다.작업을 단순화하기 위해 대부분의 작업은 재귀적인 개인 중첩 함수를 통해 수행됩니다.

import json

try:
    STRING_TYPE = basestring
except NameError:
    STRING_TYPE = str  # Python 3

def find_values(id, obj):
    results = []

    def _find_values(id, obj):
        try:
            for key, value in obj.items():  # dict?
                if key == id:
                    results.append(value)
                elif not isinstance(value, STRING_TYPE):
                    _find_values(id, value)
        except AttributeError:
            pass

        try:
            for item in obj:  # iterable?
                if not isinstance(item, STRING_TYPE):
                    _find_values(id, item)
        except TypeError:
            pass

    if not isinstance(obj, STRING_TYPE):
        _find_values(id, obj)
    return results

json_repr = '{"P1": "ss", "Id": 1234, "P2": {"P1": "cccc"}, "P3": [{"P1": "aaa"}]}'

obj = json.loads(json_repr)
print(find_values('P1', obj))

생성기를 사용하여 json.load() 뒤에 있는 개체를 검색할 수도 있습니다.

제 답변의 코드 예: https://stackoverflow.com/a/39016088/5250939

def item_generator(json_input, lookup_key):
    if isinstance(json_input, dict):
        for k, v in json_input.iteritems():
            if k == lookup_key:
                yield v
            else:
                for child_val in item_generator(v, lookup_key):
                    yield child_val
    elif isinstance(json_input, list):
        for item in json_input:
            for item_val in item_generator(item, lookup_key):
                yield item_val

이 질문은 오래되었지만 100% 답변이 없었습니다. 그래서 이것이 저의 해결책이었습니다.

기능:

  • 재귀 알고리즘
  • 리스트 검색
  • 오브젝트 검색
  • 트리에서 발견된 모든 결과를 반환합니다.
  • 키 내 부모 ID를 반환합니다.

제안사항:

  • 깊이 우선 탐색과 폭 우선 탐색을 검토한다.
  • json이 너무 크면 재귀가 문제가 될 수 있습니다. 스택 알고리즘을 조사하십시오.
   @staticmethod
    def search_into_json_myversion(jsondata, searchkey, parentkeyname: str = None) -> list:
        found = []

        if type(jsondata) is list:
            for element in jsondata:
                val = Tools.search_into_json_myversion(element, searchkey, parentkeyname=parentkeyname)
                if len(val) != 0:
                    found = found + val
        elif type(jsondata) is dict:
            if searchkey in jsondata.keys():
                pathkey = parentkeyname + '->' + searchkey if parentkeyname != None else searchkey
                found.append({pathkey: jsondata[searchkey]})
            else:
                for key, value in jsondata.items():
                    val = Tools.search_into_json_myversion(value, searchkey, parentkeyname=key)
                    if len(val) != 0:
                        found = found + val

        return found

언급URL : https://stackoverflow.com/questions/14048948/how-to-find-a-particular-json-value-by-key

반응형