Helpex - Trao đổi & giúp đỡ Đăng nhập

Cách tốt nhất để truy cập dòng thứ N của tệp csv

Bùi Quang Hiếu
· 01:35 05/12/2014
23 giờ trước

Tôi phải truy cập dòng thứ N trong tệp CSV.

Đây là những gì tôi đã làm:

import csv

the_file = open('path', 'r')
reader = csv.reader(the_file)

N = input('What line do you need? > ')
i = 0

for row in reader:
    if i == N:
        print("This is the line.")
        print(row)
        break

    i += 1

the_file.close()

... nhưng điều này không cảm thấy tối ưu. Chỉnh sửa cho chính xác: Nếu tệp lớn, tôi không muốn xem qua tất cả các dòng và tôi không muốn phải tải toàn bộ tệp vào bộ nhớ.

Tôi hy vọng một cái gì đó giống như reader[N]tồn tại, nhưng tôi đã không tìm thấy nó.

Chỉnh sửa cho câu trả lời: Dòng này (đến từ câu trả lời đã chọn) là những gì tôi đang tìm kiếm:

next(itertools.islice(csv.reader(f), N, None)
33 hữu ích 5 bình luận 40k xem chia sẻ
Hoàng Hồng Oanh
· 01:42 05/12/2014
01:42:53 05/12/2014

Nó tạo ra một chút khác biệt nhưng sẽ dễ sử dụng hơn một chút enumeratethay vì tạo biến bộ đếm của riêng bạn.

for i, row in enumerate(reader):
    if i == N:
        print("This is the line.")
        print(row)
        break

Bạn cũng có thể sử dụng itertools.islicecái được thiết kế cho kiểu kịch bản này - truy cập một phần cụ thể của một tệp có thể lặp lại mà không cần đọc toàn bộ nội dung vào bộ nhớ. Nó sẽ hiệu quả hơn một chút so với việc lặp qua các hàng không mong muốn.

with open(path, 'r') as f:
    N = int(input('What line do you need? > '))
    print("This is the line.")
    print(next(itertools.islice(csv.reader(f), N, None)))

Nhưng nếu tệp CSV của bạn nhỏ, chỉ cần đọc toàn bộ nội dung vào một danh sách, sau đó bạn có thể truy cập bằng chỉ mục theo cách thông thường. Điều này cũng có lợi thế là bạn có thể truy cập một số hàng khác nhau theo thứ tự ngẫu nhiên mà không cần phải đặt lại trình đọc csv.

my_csv_data = list(reader)
print(my_csv_data[N])
40 hữu ích 3 bình luận chia sẻ
Đỗ Nam Lộc
· 01:42 05/12/2014
01:42:33 05/12/2014

Giải pháp của bạn thực sự không tệ. Nâng cao trình lặp tệp đến dòng bạn muốn là một cách tiếp cận tốt và được sử dụng trong nhiều trường hợp như thế này.

Tuy nhiên, nếu bạn muốn nó ngắn gọn hơn, bạn có thể sử dụng nextenumeratevới một biểu thức trình tạo :

import csv

the_file = open('path', 'r')
reader = csv.reader(the_file)

N = int(input('What line do you need? > '))

line = next((x for i, x in enumerate(reader) if i == N), None)
print(line)

the_file.close()

Trong Noneđó là những gì sẽ được trả lại nếu dòng không được tìm thấy ( Nquá lớn). Bạn có thể chọn bất kỳ giá trị nào khác.


Bạn cũng có thể mở tệp bằng câu lệnh with để tự động đóng tệp:

import csv

with open('path', 'r') as the_file:
    reader = csv.reader(the_file)

    N = int(input('What line do you need? > '))

    line = next((x for i, x in enumerate(reader) if i == N), None)
    print(line)

Nếu bạn thực sự muốn cắt giảm kích thước, bạn có thể làm:

from csv import reader
N = int(input('What line do you need? > '))
with open('path') as f:
    print(next((x for i, x in enumerate(reader(f)) if i == N), None))
8 hữu ích 1 bình luận chia sẻ
Ngô Duy Luận
· 02:24 05/12/2014
02:24:55 05/12/2014

Các itertoolsmô-đun có một số chức năng để tạo vòng lặp chuyên - và nó islice()chức năng có thể được sử dụng để dễ dàng giải quyết vấn đề này:

import csv
import itertools

N = 5  # desired line number

with open('path.csv', newline='') as the_file:
    row = next(csv.reader(itertools.islice(the_file, N, N+1)))

print("This is the line.")
print(row)

Tái bút Đối với những người tò mò, phản hồi ban đầu của tôi - cũng hoạt động (được cho là tốt hơn) - là:

    row = next(itertools.islice(csv.reader(the_file), N, N+1))
8 hữu ích 5 bình luận chia sẻ
Huỳnh Quốc Hùng
· 01:45 05/12/2014
01:45:26 05/12/2014

Bạn chỉ cần làm:

n = 2 # line to print
fd = open('foo.csv', 'r')
lines = fd.readlines()
print lines[n-1] # prints 2nd line
fd.close()

Hoặc thậm chí tốt hơn để sử dụng ít bộ nhớ hơn bằng cách không tải toàn bộ tệp vào bộ nhớ:

import linecache
n = 2
linecache.getline('foo.csv', n)
6 hữu ích 5 bình luận chia sẻ
Trịnh Nguyên Phong
· 01:42 05/12/2014
01:42:20 05/12/2014

Bạn có thể thu nhỏ forvòng lặp của mình thành một biểu thức hiểu, ví dụ:

row = [row for i,row in enumerate(reader) if i == N][0]  

# or even nicer as seen in iCodez code with next and generator expression

row = next(row for i,row in enumerate(reader) if i == N)
3 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ python file csv python-3.x , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm