2017-05-29 39 views
2

我在这里面临一个问题,因为我必须收到一个json,它包含一个字符串和另一个json中某些数据的路径。如何让json路径返回给定一个字符串?

  1. 其中包含一些数据

    json1 = { 
        "Items": [{ 
            "building": "buildingA", 
            "y": [1, 2, 3], 
            "yl": "A,B,C", 
            "xl": "Data", 
            "x": [1, 2, 3] 
           }, 
           { 
            "y": [4, 5, 6], 
            "x": [1, 2, 3], 
            "predio": "BuildingB", 
            "yl": "D,E,F", 
            "xl": "Data" 
           }] 
    } 
    
  2. 和含有所需值的路径中的JSON的JSON:

    json2 = { 
        "y": "y//1", 
    } 
    

我试图使此代码解决问题:

def size2(a,i): 
x=a.split('//') 
y=len(x) 
if y ==1: 
    return i[x[0]] 
elif y==2: 
    return i[x[0]][x[1]] 
elif y==3: 
    return i[x[0]][x[1]][x[2]] 

y=json2['y'] 
for i in json1['Items']: 
print(i['y'][1])  #this way works 
print(size2(y,i))  #this way fails 

的错误信息是:

TypeERROR: list indices must be integers, not str 

有谁知道如何解决这个问题?

+0

是的。使用整数标记而不是字符串。 –

+1

非讽刺性的实际帮助:当您执行列表访问时,它将返回JSON数据中的成员,该成员是* string *,然后尝试用于后续索引访问,这会引发错误。将结果转换为int:'int(x [1])'。 –

回答

2

你可以这样即假设由所有数字字符的任何路径组件是一个整数做序列索引:

def size2(y, i): 
    obj = i 
    for comp in ((int(z) if z.isdigit() else z) for z in y.split('//')): 
     obj = obj[comp] 
    return obj 

y = json2['y'] 
for i in json1['Items']: 
    print(size2(y, i)) # this way now works 

size2()功能可以更简洁,通过使用内置的reduce()功能进行

def size2(y, i): 
    return reduce(lambda obj, v: obj[int(v) if v.isdigit() else v], y.split('//'), i) 
+0

是的,我也认为是这样的。只要没有字符串数字键,它就会工作。 :) – MSeifert

+0

@ MSeifert:是的。很难从问题中的最小信息中知道我们的哪个答案会更合适。你的方法可能更多是“Pythonic”,因为它使用EAFP而不是LBYL。 – martineau

2

正如在评论中已经指出的那样,简单地转换指数为整数索引之前,一个序列:

def size2(a,i): 
    x = a.split('//') 
    obj = i 
    for part in x: # using a loop you don't need to special case based on the length 
     try: 
      # Try to get it without converting to integer, for example to access dictionaries 
      obj = obj[part] 
     except TypeError: 
      # Fallback to integer indexing 
      obj = obj[int(part)] 
    return obj 
相关问题