lic*_*gwu 25 python search json
有一个像这样的json:
{
"P1": "ss",
"Id": 1234,
"P2": {
"P1": "cccc"
},
"P3": [
{
"P1": "aaa"
}
]
}
Run Code Online (Sandbox Code Playgroud)
P1如果没有迭代所有json,我怎么能找到所有的价值?
PS:P1可以在json的任何地方.
如果没有方法可以做到这一点,你能告诉我如何遍历json吗?
mar*_*eau 20
正如我在其他答案中所说,我认为没有办法找到与"P1"密钥相关的所有值而不迭代整个结构.然而,我已经想出了更好的方法来做到这一点,当我看到一个不同的问题的接受的答案如何从JSON获取字符串对象而不是Unicode?
基本思想是使用仅接受的object_hook参数json.loads()来观察正在解码的内容并检查所寻求的值.注意:这仅在表示为JSON object(即大括号括起来的东西{})时才有效,如示例json中所示.
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)
Run Code Online (Sandbox Code Playgroud)
输出:
[u'cccc', u'aaa', u'ss']
Run Code Online (Sandbox Code Playgroud)
Sea*_*han 12
前几天我遇到了同样的问题.我结束了搜索整个对象,并考虑了列表和dicts.以下代码段允许您搜索多个键的第一个匹配项.
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))
Run Code Online (Sandbox Code Playgroud)
它返回一个dict,键是搜索的键.Haystack预计已经是一个Python对象了,所以在将它传递给deep_search之前你必须先做json.loads.
欢迎任何评论优化!
Abh*_*jit 11
我解决这个问题的方法会有所不同.
由于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']
Run Code Online (Sandbox Code Playgroud)
将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')
Run Code Online (Sandbox Code Playgroud)
(其中a是字符串)
示例代码忽略了数组.添加它作为练习.
使用json的JSON到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)
Run Code Online (Sandbox Code Playgroud)
小智 5
请记住,json只是一个字符串,使用具有alook-ahead和look-behind的正则表达式可以非常快速地完成此任务。
通常,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']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
61682 次 |
| 最近记录: |