【问题标题】:Errors when reading column name from csv files and saving as list从 csv 文件读取列名并保存为列表时出错
【发布时间】:2018-01-02 14:00:00
【问题描述】:

我有一个包含 15,000 多个 csv 文件的文件夹。它们都有不同数量的列名。

大多数文件的第一行作为列名(数据属性),如下所示:

Name Date Contact Email 
a     b     c       d
a2    b2    c2      d2

我想要做的是读取所有文件的第一行,将它们存储为列表,然后将该列表写入新的 csv 文件。

这是我到目前为止所做的:

import csv
import glob 
list=[]
files=glob.glob('C:/example/*.csv')
for file in files :
    f = open(file)
    a=[file,f.readline()]
    list.append(a)

with open('test.csv', 'w') as testfile:
     csv_writer = csv.writer(testfile)
     for i in list:
         csv_writer.writerow(i)

当我尝试这段代码时,结果如下:

[('C:/example\\example.csv', 'Name,Date,Contact,Email\n'), ('C:/example\\example2.csv', 'Address,Date,Name\n')]

因此,在制作的 csv 中,每个文件的所有属性都进入第二列,使其看起来像这样(由于某种原因,中间有一个空行): New CSV file made

此外,在浏览文件时,我遇到了另一个错误:

UnicodeDecodeError: 'cp949' codec can't decode byte 0xed in position 6: illegal multibyte sequence

所以我在第一行包含了这段代码,但它没有说文件无效。

import codecs
files=glob.glob('C:/example/*.csv') 
fileObj = codecs.open( files, "r", "utf-8" )

我在 stackflow 上阅读了答案,但找不到与我的问题相关的答案。感谢您的回答。

【问题讨论】:

  • 首先,你不应该使用list 作为变量名。
  • 如果我正确理解您的目标,请尝试将 a=[file,f.readline()] 替换为 a = next(reader),如果可行,请告诉我。
  • 另外,您正在使用 with ... as ... 对您的 outfile 遵循良好的上下文管理器实践,但您也应该对每个 infile 执行此操作。
  • @JasonStein 列一个这样的列表是我的目标。("Filename","Column1","Column2"]。 reader 没有定义,是在不同的模块中吗?
  • 对不起!没有仔细阅读。既然您已经在使用csv,您是否检查过csv.reader 的文档?它将创建一个生成器,一次读取一行 csv。调用next 将读取一行。所以我的建议是:for file in files: with open(file, 'r') as infile: reader = csv.reader(infile), headers = next(reader)(对单行表示歉意,应该是 4)。那么headers 将是标题列表,file 将是字符串形式的文件名。

标签: python list csv


【解决方案1】:

好的,所以

import csv
import glob 
list=[]
files=glob.glob('C:/example/*.csv')
for file in files :
    f = open(file)
    a=[file,f.readline()]
    list.append(a)

您在这里打开文件,然后创建一个列表,其中列标题为字符串(注意这意味着它们看起来像“Column1,Column2”)和文件名。所以 [("文件名", "Column1, Column2")] 所以你需要在','上拆分它:

for file in files :
    f = open(file)
    a=[file] + f.readline().split(',')

现在我们有了:

["filename", ("Column1", "Column2")]

所以它仍然会打印到错误的文件中。我们需要连接列表。

    a=[file] + f.readline().split(',')

所以我们得到:

 ["filename", "Column1", "Column2"]

您应该在使用f.close() 打开每个文件后关闭它,或者在循环中使用上下文管理器,例如:

for file in files :
    with open(file) as f:
        a=[file] + f.readline()
        list.append(a)

更好的解决方案以及我将如何编写它:

import csv
import glob

files = glob.glob('mydir/*.csv')
lst = list()

for file in files:
    with open(file) as f:
        reader = csv.reader(f)
        lst.append(next(reader))


try:
    with open(files,'r'.encoding='utf8') as f:
        # do things
except UnicodeError:
    with open(files,'r'.encoding='utf8') as f:
        # do things

【讨论】:

  • 感谢您的回答。我试过你的代码添加withsplit。尽管如此,输出是带有文件名的 column1 和带有所有属性的 column2。我想我解释错了,因为我的英语不是很好。我想要做的是 [("Filename","Column1","Column2"] 所以每个属性都会在新的 csv 文件中创建列。
  • 对不起,我搞砸了。我已经更新了代码。您需要连接这两个列表。它仍然是一个列表中的列表。
  • 使用你写的最后一个代码,我应该在split(',') 旁边添加f.readline() 对吗?使用 + 导致 TypeError 说无法将列表转换为 str
  • 不,这是错误的。对不起,我只是在测试它,发现file 不是一个列表。
  • 所以略有改动。做a = [file] + f.readline().split(',') 我很高兴我回来检查我的答案。那是一个愚蠢的错误。无论如何,我认为这不会是正确的。
【解决方案2】:

一点点整理、适当的上下文管理和使用csv.reader

import csv
import glob 
list=[]
files=glob.glob('C:/example/*.csv')
with open('test.csv', 'w') as testfile:
    csv_writer = csv.writer(testfile)
    for file in files:
        with open(file, 'r') as infile:
            reader = csv.reader(infile)
            headers = next(reader)
            lst = [file] + headers
            writer.writerow(lst)

这将写入一个新的 csv,每个 infile 有一行,每一行是 filename, column1, column2, ...

【讨论】:

  • 感谢您的帮助!但是每行之间仍然有一个空格。你知道如何解决这个问题吗?以及如何从文件名中删除目录?
  • 不确定空格,但file = file[file.rfind('\\') + 1:] 会将文件名剥离为最后一个反斜杠之后的任何内容
  • 效果很好。只需修复空格和UnicodeDecodeError: 'cp949' codec 。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
  • 2016-12-19
  • 2017-05-17
  • 2014-06-12
  • 1970-01-01
相关资源
最近更新 更多