当列#和行#已知时,DictReader获取一个值

时间:2015-05-31 05:03:56

标签: python csv

我收到的csv文件看起来像这样

ID, name, age, city
1, Andy, 25, Ann Arbor
2, Bella, 40, Los Angeles
3, Cathy, 13, Eureka
...
...

如果我想获得city = 3的ID,这个例子就是尤里卡。有没有办法有效地执行此操作而不是迭代每一行?我的php代码每次都会执行这个python脚本来获取值,而且我觉得每次循环遍历csv文件都非常低效。

3 个答案:

答案 0 :(得分:3)

迭代文件一次并将数据保存到字典中:

data = {}
with open('input.csv') as fin:
    reader = csv.DictReader(fin)
    for record in reader:
        data[record['ID']] = {k:v for k,v in record.items() if k <> 'ID'}

然后只需访问字典中的所需密钥:

print data[3]['city'] # Eureka

如果您想以key:value格式保存数据,可以将其保存为json文件:

import json
import csv

j = {}
with open('input.csv') as fin:
    reader = csv.DictReader(fin)
    for record in reader:
        j[record['ID']] = {k:v for k,v in record.items() if k <> 'ID'}
with open('output.json','w') as fout:
    json.dump(j,fout)

答案 1 :(得分:0)

总之:不。

正如yurib提到的,一种方法是将您的文件转换为JSON并从那里转移,或者只是转储到dict。这使您能够在需要序列化数据集时执行pickle之类的操作,或者shelve如果要将其存放在某个地方供以后使用。

另一种选择是通过使用Python内置的sqlite3支持等方式将CSV转储到可查询的数据库中。这取决于您希望开销的位置:以这种方式预处理数据可以使您不必在每次运行脚本时解析大型文件。

快速查看this answer

答案 2 :(得分:0)

  

如果我想获得ID = 3的城市,这将是尤里卡   例。有没有办法有效地做到这一点,而不是迭代   每一行?我的php代码每次都会执行这个python脚本   获得价值,我觉得循环效率很低   每次通过csv文件。

您理想的解决方案是将此Python代码包装到可以从PHP代码调用的API中。

启动时,Python代码会将文件加载到数据结构中,然后等待您的请求。

如果文件非常大,您的Python脚本会将其加载到数据库中并从那里读取。

然后,您可以选择返回字符串或json对象。

以下是使用Flask

的示例
import csv
from flask import Flask, request, abort

with open('somefile.txt') as f:
   reader = csv.DictReader(f, delimiter=',')
   rows = list(reader)
   keys = row[0].keys()

app = Flask(__name__)

@app.route('/<id>')
@app.route('/')
def get_item():
    if request.args.get('key') not in keys:
        abort(400) # this is an invalid request
    key = request.args.get('key')
    try:
        result = next(i for i in rows if i['id'] == id)
    except StopIteration:
        # ID passed doesn't exist
        abort(400)
    return result[key]

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

你会这样称呼:

http://localhost:5000/3?key=city