制作文件的副本并删除符合条件的行?

时间:2016-02-03 15:41:00

标签: python parsing

我想用python解析csv文件。为此,我想创建同一文件的副本,然后逐行解析。

如果其中一行符合条件,我希望从临时文件中删除该行,并将其放置到新文件中。

通过这种方式,我可以使tmp越来越小,因为它遍历列表,因此解析的次数较少,并且在解析结束时查看临时文件是否为空,并确认我的解析工作得很好。然而,我不会损坏原始文件。

让我们说原始文件包含:

AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC
AAAAAAAAAA
BBBBBBBBBB

然后我有一个清单

list = [AAAAAAAAA, BBBBBBBBBB,CCCCCCCCCC]

我可以做以下几点:

for x in list:
   for line in tmpCsv:
       if x in line:
            #remove line from tmpCsv place it to file x.CSV

2 个答案:

答案 0 :(得分:2)

文件系统无法正常工作。您无法从磁盘上的文件中间有效地删除某些内容。为了模拟这个动作,操作系统首先复制文件中每个字节后面的删除行以掩盖“漏洞”,最后文件丢弃结束字节。以这种方式执行的每行删除都具有O(n)复杂度,其中n是文件大小,并且删除所有行需要O(n 2 ) - 这很慢。

如果文件足够小,您可以读取整个文件并保留在内存中。如果它们太大而无法保存在RAM(千兆字节)中,请逐个读取并分别处理每个(如果可能的话)。

不需要删除匹配的行来执行您显然想要执行的操作。您可以只计算匹配的行数,如果数字为零则打印错误。

可以实现更高效的实施,但这应该适用于开始:

for x in list:
   numberOfLinesMatched = 0
   for line in tmpCsv:
       if x in line:
           numberOfLinesMatched += 1 # possibly break here
   if numberOfLinesMatched == 0:
       ... # print an error, not found in the file

答案 1 :(得分:1)

据推测,解析后的数据将小于整个文件。因此,将较小的集合放在外部for循环上是正确的。但是你应该只需一次就可以做到这一点。下面我举一个潜在解决方案的例子。

这会逐行读取文件。如果该行符合第2段中描述的条件,则将其放在一个文件中。如果它不符合条件,则将其放在不同的文件中。

import os
if os.path.exists("match.csv") or os.path.exists("nonmatch.csv"):
    raise False, "I AM NOT OVERWRITING A FILE"
originalCsv = open(csvFile,'r')
matchFile = open("match.csv","w"
nonmatchFile = open("nonmatch.csv","w"
while 1:
    line = originalCsv.read()
    if line == '': break
    if line == meetsCondition:
        nonmatchFile.writelines(line)
    else:
        matchFile.writelines(line)
 matchFile.close()
 nonmatchFile.close()
 originalCsv.close()