如何在python中删除CSV行
我试图比较两个csv文件(fileA和fileB),并从fileA中删除在fileB中找不到的任何行。我希望能够做到这一点,而无需创建第三个文件。我原以为我可以使用csv编写器模块来完成这项工作,但现在我在猜测自己 目前,我正在使用以下代码记录文件B中的比较数据:如何在python中删除CSV行,python,csv,python-2.7,module,delete-row,Python,Csv,Python 2.7,Module,Delete Row,我试图比较两个csv文件(fileA和fileB),并从fileA中删除在fileB中找不到的任何行。我希望能够做到这一点,而无需创建第三个文件。我原以为我可以使用csv编写器模块来完成这项工作,但现在我在猜测自己 目前,我正在使用以下代码记录文件B中的比较数据: removal_list = set() with open('fileB', 'rb') as file_b: reader1 = csv.reader(file_b) next(reader1) for r
removal_list = set()
with open('fileB', 'rb') as file_b:
reader1 = csv.reader(file_b)
next(reader1)
for row in reader1:
removal_list.add((row[0], row[2]))
这就是我被卡住的地方,我不知道如何删除行:
with open('fileA', 'ab') as file_a:
with open('fileB', 'rb') as file_b:
writer = csv.writer(file_a)
reader2 = csv.reader(file_b)
next(reader2)
for row in reader2:
if (row[0], row[2]) not in removal_list:
# If row was not present in file B, Delete it from file A.
#stuck here: writer.<HowDoIRemoveRow>(row)
打开('fileA','ab')作为文件的:
以open('fileB','rb')作为文件:
writer=csv.writer(文件a)
reader2=csv.reader(文件)
下一个(读取器2)
对于reader2中的行:
如果(第[0]行,第[2]行)不在删除列表中:
#若文件B中不存在行,则将其从文件A中删除。
#卡在这里:作家。(世界其他地区)
CSV不是数据库格式。它是作为一个整体读写的。不能删除中间的行。因此,在不创建第三个文件的情况下执行此操作的唯一方法是在内存中完全读取该文件,然后将其写出,而不包含有问题的行
但一般来说,最好使用第三个文件。正如Lennart所描述的,在迭代CSV文件时,不能在适当的位置修改它 如果您确实反对创建第三个文件,那么您可能希望研究使用字符串缓冲区,其想法是在内存中构建文件的新内容。在脚本结束时,可以将缓冲区的内容写入文件A
from cStringIO import StringIO
with open('fileB', 'rb') as file_b:
new_a_buf = StringIO()
writer = csv.writer(new_a_buf)
reader2 = csv.reader(file_b)
next(reader2)
for row in reader2:
if (row[0], row[2]) not in removal_list:
writer.writerow(row)
# At this point, the contents (new_a_buf) exist in memory
with open('fileA', 'wb') as file_a:
file_a.write(new_a_buf.getvalue())
此解决方案使用withinplace=True
,它写入临时文件,然后在文件末尾自动将其重命名为您的文件名。不能从文件中删除行,但可以仅用所需的行重写文件
如果关键字参数inplace=1
被传递到fileinput.input()
或fileinput
构造函数,则该文件被移动到备份文件,标准输出被定向到输入文件(如果与备份文件同名的文件已经存在,则将以静默方式替换)。这样就可以编写一个过滤器,在适当的位置重写其输入文件
菲拉
文件
菲拉
这里需要注意的是:如果输入文件太大,可能会耗尽系统的可用内存。您也可以直接写入另一个文件,并在最后重命名它,这就是我的解决方案does@jamylak,我完全同意你的看法。这正是我在这种情况下要做的。我只是觉得这将是有用的,因为在技术上满足了询问者的要求。是一个基于平面文件的数据库,其驱动程序包含在Python的现代版本中。考虑到您正在尝试做的事情,这可能是一个更好的选择。很抱歉这个愚蠢的问题,但这将创建一个文件B的精确副本,不是吗?这是一个微妙的改进,在解释中没有提到:这段代码使用一个集合,一个比列表更优化的数据结构来回答“此数据存在吗?”(每次都必须迭代)。@David Op还使用了一组经过深思熟虑的变量。他/她显然这样做了。好吧,一点建议-不要将其称为删除“列表”,否则像我这样头脑呆滞的人会对变量的类型感到困惑。=)什么版本的python?我不相信这个语法是2.4compatible@justin你把它标记为2.7?您只需对r中的行使用
set((行[0],行[1])
h1,h2,h3
a,b,c
d,e,f
g,h,i
j,k,l
h1,h2,h3
a,b,c
1,2,3
g,h,i
4,5,6
import fileinput, sys, csv
with open('fileB', 'rb') as file_b:
r = csv.reader(file_b)
next(r) #skip header
seen = {(row[0], row[2]) for row in r}
f = fileinput.input('fileA', inplace=True) # sys.stdout is redirected to the file
print next(f), # write header as first line
w = csv.writer(sys.stdout)
for row in csv.reader(f):
if (row[0], row[2]) in seen: # write it if it's in B
w.writerow(row)
h1,h2,h3
a,b,c
g,h,i