Пропускайте заголовки під час редагування файлу csv за допомогою Python


209

Я використовую наведений нижче код для редагування csv за допомогою Python. Функції, що викликаються у кодовій формі верхньої частини коду.

Проблема: Я хочу, щоб наведений нижче код почав редагувати csv з 2-го ряду, я хочу, щоб він виключив 1-й рядок, який містить заголовки. Зараз він застосовує функції лише для 1-го ряду, і мій рядок заголовка змінюється.

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()

Я намагався вирішити цю проблему, ініціалізуючи rowзмінну до, 1але вона не спрацювала.

Будь ласка, допоможіть мені у вирішенні цього питання.


Відповіді:


370

Ваша readerзмінна є ітерабельною, перебираючи її, ви отримуєте рядки.

Щоб пропустити один елемент перед циклом, просто зателефонуйте next(reader, None)та проігноруйте повернене значення.

Ви також можете трохи спростити свій код; використовувати відкриті файли як менеджери контексту, щоб автоматично закривати їх:

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.

Якщо ви хочете , щоб написати заголовок у вихідний файл необробленого, який легко теж передавати висновок next()на writer.writerow():

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

22
Альтернативою також є використання, for row in islice(reader, 1, None)хоча менш чітке, ніж nextдля більшості простих завдань "пропустити один рядок", для пропуску декількох рядків заголовків (або отримання лише певних фрагментів тощо), це досить зручно
— Джон Клементс

Я розглядаю можливість використанняtry: writer.write(next(reader))... except StopIteration: # handle empty reader
— Джон Клементс

@JonClements: Можливо. Це працює досить добре, не вчити про try:/ except:.
— Martijn Pieters

1
@JonClements: Перевага явної nextітерації в тому, що вона "безкоштовна"; isliceобернеться readerназавжди додаванням (мабуть, дуже невеликою кількістю) накладних витрат до кожної ітерації. consumeРецепт відitertools може бути використаний , щоб пропустити багато значень швидко, без додавання упаковки для подальшого використання, в тому випадку , якщо isliceне матиме , startале не end, так що накладні витрати не отримує нічого вам.
— ShadowRanger

120

Інший спосіб вирішити це - використовувати клас DictReader, який "пропускає" рядок заголовка і використовує його для дозволеного індексованого індексу.

Подано "foo.csv" таким чином:

FirstColumn,SecondColumn
asdf,1234
qwer,5678

Використовуйте DictReader так:

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
Я відчуваю, що це справжня відповідь, оскільки це питання, здається, є прикладом проблеми XY .
— MariusSiuram

3
DictReader - це точно дорога
— Хав'єр Аріас

4
Важливо зауважити, що це працює лише в тому випадку, якщо під час побудови DictReader ви опустите параметр імен полів. Відповідно до документації: If the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames.Див. Docs.python.org/2/library/csv.html
— BuvinJ

7

Діяння row=1нічого не змінить, тому що ви просто перезаписаєте це з результатами циклу.

Ви хочете next(reader)пропустити один ряд.


Я спробував змінити його, for row in next(reader):але це дає мені IndexError: string index out of rangeпомилку

Використовуйте його перед циклом for: next(reader); for row in reader:....
— dlazesz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.