2009-07-09 14 views
9

Tôi muốn đọc tối đa 20 dòng từ một tập tin csv:Python: StopIteration ngoại lệ và danh sách comprehensions

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

Hoạt động tốt nếu các tập tin có 20 hoặc nhiều hàng, không thành công với một ngoại lệ StopIteration khác.

Có cách nào thanh lịch để đối phó với một trình lặp có thể ném ngoại lệ StopIteration trong danh sách hiểu hay tôi nên sử dụng vòng lặp thông thường?

Trả lời

11

Bạn có thể sử dụng itertools.islice. Đây là phiên bản trình duyệt của danh sách cắt. Nếu trình vòng lặp có ít hơn 20 phần tử, nó sẽ trả về tất cả các phần tử.

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

Cảm ơn Ayman. Có vẻ như việc hiểu danh sách cần phải được cập nhật để đối phó với StopIteration, phải không? Nó xuất hiện "for" đã được cập nhật để xử lý nó (nó dừng lặp lại khi nó gặp ngoại lệ, ngầm bắt nó), và tôi không thấy lý do rõ ràng cho việc hiểu danh sách không làm như vậy. – Parand

+2

để bắt StopIteration liên quan đến iterable của nó, không cho các đối tượng khác như vậy trong bộ phần mềm của nó. Ví dụ c = iter (phạm vi (5)) for i in range (10): \t in i, c.next() sẽ nâng cao StopIteration ngoại lệ liên quan đến c. – Mapio

+3

Vòng lặp for KHÔNG bắt được StopIteration. Nó chỉ bắt được nó nếu nó được ném bởi phương thức tiếp theo của trình lặp, không phải nếu nó được ném vào thân vòng lặp. Trong câu hỏi của bạn, csvreader.next() tương tự với thân vòng lặp. – Miles

-1

Nếu vì bất cứ lý do bạn cũng cần phải theo dõi các số dòng, tôi muốn khuyên bạn:

rows = zip(xrange(20), csvreader) 

Nếu không, bạn có thể tước nó ra sau hoặc ... vâng, bạn nên thử tùy chọn khác tối ưu hơn từ đầu :-)

+0

Nếu bạn cần số dòng, chắc chắn bạn nên sử dụng liệt kê() .. –

0

itertools.izip (2) cung cấp cách dễ dàng làm cho tính năng hiểu danh sách hoạt động, nhưng islice sẽ là cách để thực hiện trong trường hợp này.

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

có lợi thế là nó không dựa vào len() (ví dụ: đối với apsw.cursor) – Mark

+0

'liệt kê' là đúng cách để làm điều đó , không nén một dải. – ArekBulski