Я пытаюсь сделать какой-нибудь скрипт для использования исходного CSV-файла, сравнить его с другим и заменить строки с одинаковым первым столбцом во втором файле, используя первый.

Я использую этот код:

#!/usr/bin/env python2
import csv
import sys
f = open(sys.argv[1], 'rt')
t = open(sys.argv[2], 'wt')
r = open(sys.argv[2], 'rt')
try:
    patch = csv.reader(f)
    panorama = csv.reader(r)
    target = csv.writer(t)
#   row2 = 0
    for row in patch:
#       print row[0]
        for row2 in panorama:
            print row
            print row[0], row2[0]
            if row[0] == row2[0]:
                target.writerow((row[0], row[1],row[2],row[3],row[4],row[5],row[6],row[7],row[8]))
finally:
    f.close()
    t.close()
    r.close()

К сожалению, это происходит без ошибок, но мои отладочные отпечатки ничего не печатают. Первая закомментированная печать работает правильно и печатает первый столбец моего первого файла.

Не могли бы вы помочь мне выяснить, что с этим не так?

Спасибо за вашу помощь!

0
Abraham P. 17 Дек 2015 в 05:06

3 ответа

Лучший ответ

Есть две проблемы с вашим подходом. Первый - открыть тот же файл для чтения / записи (это можно сделать с помощью такого модуля, как fileinput, но он будет грязным из-за отсутствия поддержки csv). Вторая проблема в том, что у вас есть вложенный цикл. После первой строки patch вы уже исчерпали файл panorama. То, что вам нужно, это два не вложенных цикла. Вот мой подход:

import csv
import sys

if __name__ == '__main__':
    with open(sys.argv[1], 'rt') as patch_file, \
            open(sys.argv[2], 'rt') as pano_file, \
            open(sys.argv[3], 'wt') as output_file:

        patch_lookup = {row[0]: row for row in csv.reader(patch_file)}
        pano = csv.reader(pano_file)
        output = csv.writer(output_file)

        for row in pano:
            row = patch_lookup.get(row[0], row)
            output.writerow(row)

В моем решении patch_lookup - это словарь, в котором ключом является первое поле, а значением является целая строка. Читая pano, следующая строка будет искать строку в патче и заменять ее, если применимо:

        row = patch_lookup.get(row[0], row)

После поиска мы запишем строки в вывод.

0
Hai Vu 17 Дек 2015 в 02:48

Вы не можете одновременно открыть один и тот же файл как доступный только для чтения и только для записи.

7.2 . Чтение и запись файлов open () возвращает объект файла и чаще всего используется с двумя аргументами: open (имя файла, режим). Режим может быть «r», когда файл будет только читаться, «w» только для записи (существующий файл с тем же именем будет удален).

В документации Python 2.7.11

Когда вы объявляете target = csv.writer (t) с таким t, что t = open (sys.argv [2], 'wt'), вы перезаписываете свой файл, на который указывает sys.argv [2], и поэтому вы затем не нужно сравнивать, когда вы пытаетесь прочитать Panorama = csv.reader (r), с r = open (sys.argv [2], 'rt').

0
David Nogueira 17 Дек 2015 в 02:14

Не открывайте один и тот же файл, используя как чтение, так и запись - потому что после того, как вы введете запись, содержимое исчезнет. Создайте другой файл для записи.

0
autopython 17 Дек 2015 в 02:24