2015-11-16 97 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] 
相关问题