2013-05-27 4 views
1

Я использую csv.DictReader для чтения данных из файла CSV. Когда читатель итерации, он дает словарей с ключами, взятых из заголовка CSV и значения для каждой строки:Сохранение накладных расходов памяти с помощью DictReader

with open(filename) as h: 
    data = csv.DictReader(h) 
    for row in data: 
     # row is dict 

Каждая строка представляет собой словарь с keys, и каждая строка имеет точно такие же ключи. В случае, когда значения являются целыми числами, а ключи (строки) длинны, клавиши занимают больше места в памяти, чем значения.

Можно ли перебирать строки так, чтобы клавиши каждой строки указывали на то же самое экземпляр ключей, поэтому я сохраняю пространство памяти в строке?

Обратите внимание, что я не знаю ключей заранее - они взяты из заголовка CSV. В противном случае я мог бы использовать namedtuple или __slots__

ответ

2

Вы можете использовать namedtuple; построить его из первой строки себя:

with open(filename, 'rb') as h: 
    data = csv.reader(h) 
    headers = next(data) 
    RowTuple = namedtuple('RowTuple', headers) 
    for row in data: 
     row = RowTuple(row) 

Это, по существу, что делает DictReader(); возьмите ключи из первой строки.

Отметьте, что код DictReader() создает словарь с dict(zip(self.fieldnames, row)); этот повторяет те же строки для каждой строки, и у вас есть только одна служебная память памяти: dict и хэш-значения для ключей (они пересчитываются каждый раз и кэшируются). Строки для ключей не создаются заново для каждой строки. Подход namedtuple тоже не требуется, но не нужно сохранять хэши с __slots__.

Смежные вопросы