преобразование данных CSV в dict без записи файла на диск

#python #csv #unzip

#python #csv #распаковать

Вопрос:

Вот мой сценарий: у меня есть zip-файл, который я загружаю с requests в память, а не записываю файл. Я разархивирую данные в объект с именем myzipfile . Внутри zip-файла находится файл csv. Я хотел бы преобразовать каждую строку данных csv в словарь. Вот что у меня есть на данный момент.

 import csv
from io import BytesIO
import requests

# other imports etc. 

        r = requests.get(url=fileurl, headers=headers, stream=True)
        filebytes = BytesIO(r.content)

        myzipfile = zipfile.ZipFile(filebytes)
        for name in myzipfile.namelist():  
            mycsv = myzipfile.open(name).read()
            for row in csv.DictReader(mycsv):  # it fails here.
                print(row)
  

ошибки:

 Traceback (most recent call last):
  File "/usr/lib64/python3.7/csv.py", line 98, in fieldnames
    self._fieldnames = next(self.reader)
_csv.Error: iterator should return strings, not int (did you open the file in text mode?)
  

Похоже, csv.DictReader(mycsv) ожидается файловый объект вместо необработанных данных. Как преобразовать строки в mycsv объектных данных (<class 'bytes'>) в список словарей? Я пытаюсь выполнить это, не записывая файл на диск и работая непосредственно с объектами csv в памяти.

Комментарии:

1. разве это не было бы просто csv.DictReader(myzipfile.open(name)) ?

Ответ №1:

DictReader Ожидает файл или файлоподобный объект: мы можем удовлетворить это ожидание, загрузив архивированный файл в io.StringIO экземпляр.

Обратите внимание, что StringIO ожидается, что его аргументом будет a str , но чтение файла из zipfile возвращает bytes , поэтому данные должны быть декодированы. В этом примере предполагается, что csv изначально был закодирован с использованием кодировки локальной системы по умолчанию. Если это не так, необходимо передать правильную кодировку decode() .

 for name in myzipfile.namelist():
    data = myzipfile.open(name).read().decode()
    mycsv = io.StringIO(data)
    reader = csv.DictReader(mycsv)
    for row in reader:
        print(row)
  

Ответ №2:

 dict_list = [] # a list
reader = csv.DictReader(open('yourfile.csv', 'rb'))
for line in reader: # since we used DictReader, each line will be saved as a dictionary
 dict_list.append(line)
  

Комментарии:

1. попытка сделать это без записи файла на диск. возможно ли это?

2. Я полагаю, что вы также читаете файл в своем коде, это то же самое, что я делаю здесь.