2015-05-31 2 views
0

Я дал CSV-файл, который выглядит примерно такDictReader получить значение, когда столбец # и строка # известны

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

Если я хочу, чтобы получить city из ID = 3, который будет Eureka для этого примера. Есть ли способ сделать это эффективно, а не итерировать каждую строку? Мой php-код будет выполнять этот скрипт python каждый раз, чтобы получить значение, и я чувствую себя очень неэффективным, чтобы циклически перебирать файл csv каждый раз.

ответ

2

итерация над файлом один раз и сохранить данные в словарь:

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 

в случае, если вы хотите, чтобы сохраняться данные в ключ: формат значения вы можете сохранить его в виде файла 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) 
+0

Would делает этот путь будет, конечно, быстрее, чем итерация CSV-файла каждый раз, принимая CSV у файла довольно много строк? –

+0

Зачем писать данные как JSON? Чтение файла (которое может быть записано внешней системой) в память в виде dict должно быть достаточным. – Johnsyweb

+1

@Johnsyweb Я думаю, что вы правы – yurib

0

В слово: нет.

Как указано yurib, один из способов заключается в том, чтобы преобразовать ваши файлы в JSON и перейти оттуда или просто свалить на dict. Это дает вам возможность делать такие вещи, как pickle, если вам нужно сериализовать ваш набор данных, или shelve, если вы хотите занести его куда-нибудь для последующего использования.

Другим вариантом является сброс CSV в запрашиваемую базу данных путем использования чего-то вроде встроенной поддержки Python sqlite3. Это зависит от того, где вы хотите, чтобы ваши накладные расходы лежали: предварительная обработка ваших данных таким образом избавляет вас от необходимости синтаксического анализа большого файла каждый раз, когда выполняется ваш скрипт.

Отъезд this answer для краткого уточнения.

0

Если я хочу получить город ID = 3, который был бы Eureka для этого примера . Есть ли способ сделать это эффективно, а не итерации каждой строки? Мой php-код будет выполнять этот скрипт python каждый раз , чтобы получить значение, и я чувствую себя очень неэффективным для цикла через CSV-файл каждый раз.

Ваше идеальное решение состоит в том, чтобы обернуть этот код Python в API, который вы можете вызвать из своего PHP-кода.

При запуске код 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 
Смежные вопросы