2009-07-09 3 views
9

Я хотел бы прочитать не более 20 строк из файла CSV:Python: StopIteration исключение и списочные

rows = [csvreader.next() for i in range(20)] 

отлично работает, если файл имеет 20 или более строк, терпит неудачу с исключением StopIteration иначе.

Есть ли элегантный способ справиться с итератором, который может вызвать исключение StopIteration в понимании списка или использовать регулярный цикл?

ответ

11

Вы можете использовать itertools.islice. Это итераторная версия списка. Если итератор имеет менее 20 элементов, он вернет все элементы.

import itertools 
rows = list(itertools.islice(csvreader, 20)) 
+0

Thanks Ayman. Похоже, что переосмысления списков необходимо обновить, чтобы справиться с StopIteration, нет? Он кажется, что «для» уже обновлен, чтобы справиться с ним (он прекращает итерацию, когда сталкивается с этим исключением, неявно ловя его), и я не вижу очевидной причины, по которой переписные листы не будут делать то же самое. – Parand

+2

для улавливания StopIteration относительно его итерации, а не других подобных объектов в его наборе. Так, например с = ITER (диапазон (5)) для г в диапазоне (10): \t печати I, c.next() поднимет StopIteration исключение относительно С. – Mapio

+3

Цикл for НЕ НЕЯТНО улавливает StopIteration. Он только улавливает его, если его выбрасывает следующий метод итератора, а не если он забрасывается в тело цикла. В вашем вопросе csvreader.next() аналогичен телу цикла. – Miles

-1

Если по какой-либо причине вам необходимо также следить за номером строки, я бы порекомендовал вам:

rows = zip(xrange(20), csvreader) 

Если нет, то вы можете лишить его после или ... ну, вы бы лучше попробовать другой вариант более оптимальный с самого начала :-)

+0

Если вам нужен номер строки, вы должны использовать enumerate() .. –

0

itertools.izip (2) предоставляет возможность легко сделать списочные работать, но islice выглядит путь в этом случае.

from itertools import izip 
[row for (row,i) in izip(csvreader, range(20))] 
+0

, который имеет то преимущество, что он не полагается на len() (например, для apsw.cursor) – Mark

+0

'enumerate' - это правильный способ сделать это , без изменения диапазона. – ArekBulski