2017-05-29 60 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 
相關問題