2015-11-16 146 views
2

我有下面的Python代碼的Python ----類型錯誤:字符串索引必須是整數

from flask import Flask, jsonify, json 

app = Flask(__name__) 

with open('C:/test.json', encoding="latin-1") as f: 
    dataset = json.loads(f.read()) 

@app.route('/api/PDL/<string:dataset_identifier>', methods=['GET']) 
def get_task(dataset_identifier): 
    global dataset 
    dataset = [dataset for dataset in dataset if dataset['identifier'] == dataset_identifier] 
    if len(task) == 0: 
     abort(404) 
    return jsonify({'dataset': dataset}) 

if __name__ == '__main__': 
    app.run(debug=True) 

Test.json看起來是這樣的:

{ 
    "dataset": [{ 
         "bureauCode": [ 
              "016:00" 
             ], 
         "description": "XYZ", 
         "contactPoint": { 
              "fn": "AG", 
              "hasEmail": "mailto:[email protected]" 
             }, 
         "distribution": [ 
              { 
               "format": "XLS", 
               "mediaType": "application/vnd.ms-excel", 
               "downloadURL": "https://www.example.com/xyz.xls" 
              } 
             ], 
         "programCode": [ 
              "000:000" 
             ], 
         "keyword": [         "return to work", 
            ], 
         "modified": "2015-10-14", 
         "title": "September 2015", 
         "publisher": { 
              "name": "abc" 
             }, 
         "identifier": US-XYZ-ABC-36, 
         "rights": null, 
         "temporal": null, 
         "describedBy": null, 
         "accessLevel": "public", 
         "spatial": null, 
         "license": "http://creativecommons.org/publicdomain/zero/1.0/", 
         "references": [ 
              "http://www.example.com/example.html" 
             ] 
        } 
       ], 
    "conformsTo": "https://example.com" 
} 

當我傳遞變量的URL像這樣:http://127.0.0.1:5000/api/PDL/1403 我得到以下錯誤:TypeError: string indices must be integers

知道「標識符」字段是一個字符串,我通過以下網址:

http://127.0.0.1:5000/api/PDL/"US-XYZ-ABC-36" 
http://127.0.0.1:5000/api/PDL/US-XYZ-ABC-36 

我不斷收到以下錯誤:

TypeError: string indices must be integers 

什麼我錯過這裏的任何想法?我是Python新手!

+2

不要在你的列表中理解使用相同的變量名作爲你的迭代器和列表 –

+1

不但OP使用的名稱兩次名單補償裏面,但他也被分配了導致同名。 –

+0

@DanielRoseman:在Py2中,這也會減慢很多東西,因爲列表組件會共享作用域(因此,所有使用'dataset'的組件都會共享全局組件,包括重新分配全局的組件),使其變得緩慢,而不僅僅是混亂。至少在Py3中,列表組件(如生成器表達式和set/dict組件)具有閉包範圍,可以保護它們免受特定的低效率影響。 – ShadowRanger

回答

1

你現在的問題是,在列表理解迭代過程中,第一個迭代從意味着dictjson.loads -ed到dict的關鍵(dict小號重申他們鍵)更名dataset。因此,當您嘗試使用dataset['identifier']查找dataset中的值時,dataset不再是dict,而是您正在迭代的str密鑰。

停止重複使用相同的名稱來表示不同的事物。

從您發佈的JSON,你可能想的是一樣的東西:

with open('C:/test.json', encoding="latin-1") as f: 
    alldata = json.loads(f.read()) 

@app.route('/api/PDL/<string:dataset_identifier>', methods=['GET']) 
def get_task(dataset_identifier): 
    # Gets the list of data objects from top level object 
    # Could be inlined into list comprehension, replacing dataset with alldata['dataset'] 
    dataset = alldata['dataset'] 
    # data is a single object in that list, which should have an identifier key 
    # data_for_id is the list of objects passing the filter 
    data_for_id = [data for data in dataset if data['identifier'] == dataset_identifier] 
    if len(task) == 0: 
     abort(404) 
    return jsonify({'dataset': data_for_id}) 
+1

注意:我沒有使用'global'關鍵字,因爲如果名稱不在本地範圍內,從名稱中讀取而不寫入它自然會從全局變量中讀取。如果我們像您一樣使用了'global',並且重寫了'dataset',則路由在第一次使用後可能會失敗,因爲第一次使用會將全局重寫爲完全不同的類型。 – ShadowRanger

+0

謝謝!這適用於我所有的JSON數據。我有CSV數據,我還需要以CSV格式顯示。對此有何意見? – aghad

+0

@aghad:使用['csv'模塊](https://docs.python.org/3/library/csv.html)。不要試圖手動解析/生成CSV。 – ShadowRanger

2

的問題是,您要遍歷字典,而不是裏面的數據源的列表。因此,您正在遍歷字典的鍵,它們是字符串。另外,正如前面提到的那樣,如果對列表和迭代器變量使用相同的名稱,則會遇到問題。

這爲我工作:

[ds for ds in dataset['dataset'] if ds['identifier'] == dataset_identifier] 
相關問題