Bỏ qua các tiêu đề khi chỉnh sửa tệp csv bằng Python


208

Tôi đang sử dụng mã được giới thiệu bên dưới để chỉnh sửa csv bằng Python. Các hàm được gọi trong mẫu mã phần trên của mã.

Vấn đề: Tôi muốn mã được giới thiệu bên dưới bắt đầu chỉnh sửa csv từ hàng thứ 2, tôi muốn nó loại trừ hàng thứ 1 chứa tiêu đề. Ngay bây giờ, nó chỉ áp dụng các chức năng trên hàng đầu tiên và hàng tiêu đề của tôi đang được thay đổi.

in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
    row[13] = handle_color(row[10])[1].replace(" - ","").strip()
    row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
    row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
    row[10] = handle_gb(row[10])[0].strip()
    row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
    row[15] = handle_addon(row[10])[1].strip()
    row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
    writer.writerow(row)
in_file.close()    
out_file.close()

Tôi đã cố gắng giải quyết vấn đề này bằng cách khởi tạo rowbiến 1nhưng nó không hoạt động.

Xin hãy giúp tôi giải quyết vấn đề này.


Câu trả lời:


369

readerBiến của bạn là một lần lặp, bằng cách lặp qua nó, bạn lấy ra các hàng.

Để làm cho nó bỏ qua một mục trước vòng lặp của bạn, chỉ cần gọi next(reader, None)và bỏ qua giá trị trả về.

Bạn cũng có thể đơn giản hóa mã của mình một chút; sử dụng các tệp đã mở làm trình quản lý bối cảnh để đóng chúng tự động:

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   reader = csv.reader(infile)
   next(reader, None)  # skip the headers
   writer = csv.writer(outfile)
   for row in reader:
       # process each row
       writer.writerow(row)

# no need to close, the files are closed automatically when you get to this point.

Nếu bạn muốn viết tiêu đề cho tập tin đầu ra chưa qua chế biến, đó là dễ dàng quá, vượt qua sản lượng next()để writer.writerow():

headers = next(reader, None)  # returns the headers or `None` if the input is empty
if headers:
    writer.writerow(headers)

22
Một cách khác cũng được sử dụng for row in islice(reader, 1, None)- mặc dù ít rõ ràng hơn so nextvới hầu hết các công việc "bỏ qua một dòng" đơn giản, để bỏ qua nhiều hàng tiêu đề (hoặc chỉ nhận một số đoạn nhất định, v.v ...) nó khá tiện dụng
Jon Clements

Tôi sẽ cân nhắc sử dụngtry: writer.write(next(reader))... except StopIteration: # handle empty reader
Jon Clements

@JonClements: Có lẽ. Điều này hoạt động đủ tốt mà không cần phải dạy về try:/ except:.
Martijn Pieters

1
@JonClements: Ưu điểm của nextphép lặp rõ ràng là nó "miễn phí"; islicesẽ bao bọc phần readerbổ sung mãi mãi (một lượng rất nhỏ) được thừa nhận vào mỗi lần lặp. Công consumethức từitertools có thể được sử dụng để bỏ qua nhiều giá trị một cách nhanh chóng, mà không cần thêm gói vào sử dụng tiếp theo, trong trường hợp islicesẽ có startnhưng không end, vì vậy chi phí không mang lại cho bạn bất cứ điều gì.
ShadowRanger

120

Một cách khác để giải quyết điều này là sử dụng lớp DictReader, "bỏ qua" hàng tiêu đề và sử dụng nó để cho phép lập chỉ mục được đặt tên.

Cho "foo.csv" như sau:

FirstColumn,SecondColumn
asdf,1234
qwer,5678

Sử dụng DictReader như thế này:

import csv
with open('foo.csv') as f:
    reader = csv.DictReader(f, delimiter=',')
    for row in reader:
        print(row['FirstColumn'])  # Access by column header instead of column number
        print(row['SecondColumn'])

21
Tôi cảm thấy như đây là câu trả lời thực sự, vì câu hỏi dường như là một ví dụ về vấn đề XY .
MariusSiuram

3
DictReader chắc chắn là con đường để đi
Javier Arias

4
Điều quan trọng cần lưu ý là điều này chỉ hoạt động nếu bạn bỏ qua tham số tên trường khi xây dựng DictReader. Theo các tài liệu hướng dẫn: If the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames.Xem docs.python.org/2/library/csv.html
BuvinJ

7

Không làm row=1gì thay đổi, vì bạn sẽ ghi đè lên kết quả của vòng lặp.

Bạn muốn làm next(reader) để bỏ qua một hàng.


Tôi đã thử thay đổi nó for row in next(reader):nhưng nó gây ra IndexError: string index out of rangelỗi cho tôi

Sử dụng nó trước vòng lặp for: next(reader); for row in reader:....
dlazesz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.