2015-07-11 2 views
-2

Desktop.zip содержит несколько текстовых файлов. fun.py - это программа python, которая будет печатать имя текстовых файлов из zip, а также количество строк в каждом файле. Здесь все хорошо. Но он также импортирует этот вывод в один CSV-файл. Код: -Импортировать вывод в файл CSV

import zipfile, csv 

file = zipfile.ZipFile("Desktop.zip", "r") 
inputcsv = input("Enter the name of the CSV file: ") 
csvfile = open(inputcsv,'a') 

#list file names 
for name in file.namelist(): 
    print (name) 

# do stuff with the file object 
for name in file.namelist(): 
    with open(name) as fh: 
     count = 0 
     for line in fh: 
      count += 1 
     print ("File " + name + "line(s) count = " + str(count)) 

     b = open(inputcsv, 'w') 
     a = csv.writer(b) 

     data = [name, str(count)] 
     a.writerows(data) 


file.close() 

Я ожидаю выход в CSV файл, как: -

test1.txt, 25 
test2.txt, 10 

Но я получаю этот выход в CSV файл: -

t,e,s,t,1,.,t,x,t 
2,5 
t,e,s,t,2,.,t,x,t 
1,0 

Здесь test1.txt и test2.txt - файлы в Desktop.zip, а 25 и 10 - количество строк этих файлов соответственно.

+1

код в ваш вопрос не мог бы генерироваться файл CSV вы сказать, что это сделал. – martineau

ответ

0

Код в вашем вопросе имеет несколько проблем, как указывали другие. Двумя основными являются то, что вы повторно создаете файл csv снова и снова для каждого обрабатываемого члена архива, а затем, во-вторых, передаете csvwriter.writerows() неправильные данные. Он интерпретирует каждый элемент в списке, который вы передаете, в виде отдельной строки, которая будет добавлена ​​в файл csv.

Один из способов исправить это будет только один раз открыть файл csv, прежде чем вводить цикл for, который подсчитывает строку в каждом члене архива и записывает по ней одну строку с вызовом csvwriter.writerow().

Немного другой способ, показанный ниже, использует writerows(), но передает его generator expression, который обрабатывает каждый член один на один, вместо того, чтобы звонить writerow() повторно.Он также обрабатывает каждый член поэтапно, поэтому ему не нужно одновременно считывать всю информацию в память, а затем разделить ее, чтобы получить количество строк.

Хотя вы не указали, какую версию Python вы используете, из кода в вашем вопросе, я предполагаю, что это Python 3.x, поэтому нижеприведенный ответ был написан и протестирован с этим (хотя это не составит труда заставить его работать на Python 2.7).

import csv 
import zipfile 

input_zip_filename = 'Desktop.zip' 
output_csv_filename = input("Enter the name of the CSV file to create: ") 

# Helper function.  
def line_count(archive, filename): 
    ''' Count the lines in specified ZipFile member. ''' 
    with archive.open(filename) as member: 
     return sum(1 for line in member) 

with zipfile.ZipFile(input_zip_filename, 'r') as archive: 

    # List files in archive. 
    print('Members of {!r}:'.format(input_zip_filename)) 
    for filename in archive.namelist(): 
     print(' {}'.format(filename)) 

    # Create csv with filenames and line counts. 
    with open(output_csv_filename, 'w', newline='') as output_csv: 
     csv.writer(output_csv).writerows(
      # generator expression 
      [filename, line_count(archive, filename)] # contents of one row 
       for filename in archive.namelist()) 

Пример формата содержимого в CSV-файл создан:

test1.txt,25 
test2.txt,10 
1

writerows принимает итерабельность строк, представляющих итерации строк. Вы передаете ему одну строку, поэтому она интерпретирует каждый символ каждого столбца как ячейки. Вы этого не хотите. Используйте writerow, а не writerows.

1

Я видел целый ряд вопросов:

  • Вы должны открыть файл CSV только один раз, прежде чем цикл. Откройте его внутри для цикла, отменяет информацию из предыдущей итерации цикла
  • icktoofay указал, что вы должны использовать writerow, не writerows
  • file является зарезервированным словом, вы не должны использовать его, чтобы назвать переменным. Кроме того, это не так, как описательный
  • Кажется, что вы получили имена файлов из архива, но откройте файл из каталога (а не из архива). Эти два набора файлов могут быть не идентичными.

Вот мой подход:

import csv 
import zipfile 

with open('out.csv', 'wb') as file_handle: 
    csv_writer = csv.writer(file_handle) 

    archive = zipfile.ZipFile('Desktop.zip') 
    for filename in archive.namelist(): 
     lines = archive.open(filename).read().splitlines() 
     line_count = len(lines) 
     csv_writer.writerow([filename, line_count]) 

Мой подход имеет несколько проблем, которые могут включать или не имеет значения:

  • я принимаю файлы в архиве, чтобы быть текстовый файл
  • Я открываю, читаю и разделяю линии за одну операцию. Это может не сработать для очень больших файлов.
Смежные вопросы