2015-07-11 92 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中工作)。在CSV文件的内容

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

样本格式创建:

test1.txt,25 
test2.txt,10 
1

writerows需要迭代行代表可迭代。您将它传递给一行,以便将每列的每个字符解释为一个单元格。你不想那样。使用writerow而不是writerows

1

我看到了一些问题:

  • 您应该打开CSV文件只有一次,之前的for循环。打开它里面的for循环将覆盖从以前的循环迭代
  • 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]) 

我的做法有几个问题,这可能会或可能不会事项:

  • 我假定文件归档是文本文件
  • 我在一个操作中打开,读取和拆分行。这可能不适用于非常大的文件