如何在Python中将新行添加到旧的CSV文件中?

298

我想将新行添加到旧的CSV文件中。基本上,每次运行Python脚本时都会更新它。

现在,我将旧的CSV行值存储在列表中,然后删除CSV文件并使用新列表值创建它。

我想知道是否有更好的方法来完成这个任务。

8个回答

342
with open('document.csv','a') as fd:
    fd.write(myCsvRow)

使用'a'参数打开文件可以在文件末尾添加内容而不是简单地覆盖现有内容。试试看。


4
我尝试了以下代码: fp = open(csv_filepathwithname, 'wa') writer = csv.writer(fp) somelist = [ 3,56,3,6,56] writer.writerow((somelist)) 但是只有最后一行被追加到文件中。 - laspal
3
这种方法假设要追加的项是逗号分隔的,但情况并非总是如此。因此,写入方法将无法维护 CSV 分隔符。以下答案在这方面更为健壮。 - sheth7
请提供我的CsvRow类型。 - Rémy Hosseinkhan Boucher

247

我更喜欢使用标准库中的csv模块以及with语句来处理文件,从而避免文件未关闭。

关键点是在打开文件时使用'a'进行添加操作。

import csv   
fields=['first','second','third']
with open(r'name', 'a') as f:
    writer = csv.writer(f)
    writer.writerow(fields)

如果您正在使用Python 2.7,则在Windows中可能会出现多余的换行符。您可以尝试使用'ab'代替'a'来避免这种情况,但这将导致您在Python 3.6中遇到TypeError: a bytes-like object is required, not 'str' in python and CSV。如Natacha所建议的那样添加newline=''将导致在Python 2和3之间出现向后不兼容


3
可能会出现的烦人问题:如果 CSV 文件结尾没有换行符,那么最后一行会被扩展而不是新增一行。 - Jesse Aldridge
2
这是更好的答案,应该标记为正确答案。 csv包确保正确格式化,事实上我想不出使用纯文本而不是csv的任何优点。 - Yost777
6
对我来说,这段代码会添加不必要的空行,所以我在这一行中添加了newline=''with open(r'name', 'a', newline='') as f:(在Windows上,Python 3.9) - Eugene Chabanov

36

基于@G M的回答并注意@John La Rooy的警告,我能够在'a'模式下添加一个新行。

即使在Windows中,为了避免换行问题,您必须将其声明为newline=''

现在你可以以'a'模式(不带b)打开文件。

import csv

with open(r'names.csv', 'a', newline='') as csvfile:
    fieldnames = ['This','aNew']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writerow({'This':'is', 'aNew':'Row'})

我没有尝试使用普通的写作工具(不带字典),但我认为也应该没问题。


21

如果您使用pandas,可以通过以下方式将数据框附加到现有的CSV文件:

df.to_csv('log.csv', mode='a', index=False, header=False)

使用mode='a',确保我们进行追加而不是覆盖,并且使用header=False确保仅追加df行的值,而不包括标题+值。


15

你是不是使用了'a'模式而不是'w'模式来打开文件?

请参考Python文档中的Reading and Writing Files

7.2. 读写文件

open()函数返回一个文件对象,通常用两个参数:open(filename, mode)。

>>> f = open('workfile', 'w')
>>> print f <open file 'workfile', mode 'w' at 80a0960>
第一个参数是包含文件名的字符串。第二个参数是另一个包含描述文件使用方式的几个字符的字符串。当文件只需读取时,模式可以为“r”,当文件只需写入时(具有相同名称的现有文件将被删除),“w”,而“a”则打开文件以进行附加; 写入文件的任何数据都会自动添加到结尾处。“r +”打开文件进行读取和写入。模式参数是可选的;如果省略,则假定为“r”。
在Windows上,“b”附加到模式后以二进制模式打开文件,因此还有像“rb”,“wb”和“r + b”这样的模式。Python在Windows上区分文本和二进制文件;在读取或写入数据时,文本文件中的行尾字符会自动略微更改。对于ASCII文本文件,文件数据的这种幕后修改是可以接受的,但它会破坏像JPEG或EXE文件中那样的二进制数据。在读取和写入这些文件时非常小心,请务必使用二进制模式。在Unix上,向模式附加“b”不会有害,因此您可以在所有二进制文件上独立于平台地使用它。

2
也许您可以更详细地阐述您的答案,这样它看起来就像是一个真正的答案 :-) - Areza
1
@user,我添加了一个链接 - 这对你有帮助吗? - John La Rooy

12
如果文件存在且包含数据,则可以自动生成csv.DictWriterfieldname参数。
# read header automatically
with open(myFile, "r") as f:
    reader = csv.reader(f)
    for header in reader:
        break

# add row to CSV file
with open(myFile, "a", newline='') as f:
    writer = csv.DictWriter(f, fieldnames=header)
    writer.writerow(myDict)

11

我使用以下方法在 .csv 文件中添加新行:

pose_x = 1 
pose_y = 2

with open('path-to-your-csv-file.csv', mode='a') as file_:
    file_.write("{},{}".format(pose_x, pose_y))
    file_.write("\n")  # Next line.

[注意]:

  • mode='a' 表示追加模式。

能否通过循环遍历行并在每行下方添加新行呢? - santma
1
@santma 是的,可以。你可以使用 for 来实现。 - Benyamin Jafari

6
# I like using the codecs opening in a with 
field_names = ['latitude', 'longitude', 'date', 'user', 'text']
with codecs.open(filename,"ab", encoding='utf-8') as logfile:
    logger = csv.DictWriter(logfile, fieldnames=field_names)
    logger.writeheader()

# some more code stuff 

    for video in aList:
        video_result = {}                                     
        video_result['date'] = video['snippet']['publishedAt']
        video_result['user'] = video['id']
        video_result['text'] = video['snippet']['description'].encode('utf8')
        logger.writerow(video_result) 

1
请修正您的缩进。解释也会使答案更有价值,这些答案也会吸引更多的赞。 - Mr. T
这是一些简单的代码,它以追加模式打开文件,写出一个头记录,然后处理aList中的视频记录。 - markkaufman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接