【发布时间】:2020-09-01 10:17:00
【问题描述】:
我有这个 Json 作为字符串:
json_String= {
"type": [
{
"color": "blue",
"contrast": "high",
"stock": "enough"
},
{
"color": "orange",
"contrast": "high",
"stock": "enough",
"details": "noneTobeGiven"
},
{
"color": "red",
"contrast": "low",
"stock": "enough",
"details": "noneTobeGiven"
},
{
"color": "blue",
"contrast": "high",
"stock": "enough",
"details": "noneTobeGiven"
}
]
}
从中创建一个字典:
dict1 = eval(json_String)
基于此answer,我正在尝试返回特定路径的标记的所有出现
from functools import reduce # forward compatibility for Python 3
import operator
def get_by_path(root, items):
"""Access a nested object in root by item sequence."""
return reduce(operator.getitem, items, root)
print(get_by_path(dict1, ["type", "color"]))
但是收到一个错误:
TypeError: list indices must be integers or slices, not str
我认为这是因为列表,它需要一个索引而不是 str,并试图这样调用模块:
print(get_by_path(dict1, ["type", "color"][0]))
结果是:
return reduce(operator.getitem, items, root)
KeyError: 't'
目标
对于给定的路径,假设 type.color,为每次出现返回 [color] 的所有值:
print(get_values_by_path("type.color")
[“蓝色”、“橙色”、“红色”、“蓝色”]
【问题讨论】:
-
如果您不覆盖诸如
str之类的内置关键字,这将不会那么令人困惑。 -
使用
json.loads解析 JSON,而不是eval,这就是它的用途。而且您有一个错字 - 您将索引[0]应用到["type", "color"],notdict1(实际上是一个列表)。 -
您说得对导致问题的列表。如果你还没有准备好自己实现它,那么像 jmespath、jsonpath、objectpath 这样的库可以做到这一点。
-
一般来说,您应该避免使用
eval方法(stackoverflow.com/questions/1832940/…)。这被认为是一种不好的、不安全的做法。如果要根据字面量检索对象的类型,最好使用 ast 模块中的literal_eval(stackoverflow.com/questions/15197673/…)