写完后删除python中的行

时间:2010-08-05 19:14:27

标签: python lines

好的,这是我现有的代码:

////////////// = []
for line in datafile:
    splitline = line.split()
    for item in splitline:
        if not item.endswith("JAX"):
            if item.startswith("STF") or item.startswith("BRACKER"):
                //////////.append( item )


for line in //////////
    print /////////////
   /////////// +=1
    for t in//////
        if t in line[:line.find(',')]:
            line = line.strip().split(',')
           ///////////////write(','.join(line[:3]) + '\n') 
            break

/////////////.close()
/////////////close()
///////////.close()

我想进一步优化。该文件非常大。我想删除它们匹配后匹配并写入小文件的行,以减少搜索大文件所需的时间。关于我应该怎么做的任何建议?

2 个答案:

答案 0 :(得分:1)

你无法删除文本文件中的行 - 它需要在删除的行之后移动所有数据以填补空白,并且效率非常低。

执行此操作的一种方法是使用要保留在bigfile.txt中的所有行编写临时文件,并在完成处理后删除bigfile.txt并重命名临时文件以替换它。

或者,如果bigfile.txt足够小以适应内存,则可以将整个文件读入列表并从列表中删除行,然后将列表写回磁盘。

我还会从你的代码中猜到bigfile.txt是某种CSV文件。如果是这样,那么最好将其转换为数据库文件并使用SQL进行查询。 Python内置了SQLite模块,大多数其他数据库都有第三方库。

答案 1 :(得分:0)

正如我在评论中所说,它并不像我看起来像“bigfile”的大小应该会减慢计数增加的速度。当你迭代这样的文件时,Python只是按顺序一次读取一行。

此时您可以执行的优化取决于matchesLines的大小,以及matchedLines字符串与您正在查看的文本之间的关系。

如果matchedLines很大,只需执行一次'find'就可以节省时间:

for line in completedataset:
   text = line[:line.find(',')] 
   for t in matchedLines:
        if t in text:
            line = line.strip().split(',')
            smallerdataset.write(','.join(line[:3]) + '\n') 
            break

在我的测试中,'find'花了大约300纳秒,所以如果matchLines是几百万个项目,那么你的额外第二个就在那里。

如果您正在寻找完全匹配,而不是子字符串匹配,您可以使用集合加快速度:

matchedLines = set(matchedLines)
for line in completedataset:
    target = line[:line.find(',')]
    ## One lookup and you're done!
    if target in matchedLines:
        line = line.strip().split(',')
        smallerdataset.write(','.join(line[:3]) + '\n') 

如果不匹配的目标文本看起来与看起来完全不同(例如,大多数目标是随机字符串,而匹配的列是一串名称)并且匹配的列都高于一定长度,你可以尝试通过检查子串来变得非常聪明。假设所有匹配的线都至少有5个字符......

def subkeys(s):
    ## e.g. if len(s) is 7, return s[0:5], s[1:6], s[2:7].
    return [s[i:i+5] for i in range(len(s) + 1 - 5)]

existing_subkeys = set()
for line in matchedLines:
    existing_subkeys.update(subkeys(line))

for line in completedataset:
    target = line[:line.find(',')]
    might_match = False
    for subkey in subkeys(target):
        if subkey in existing_subkeys:
            might_match = True
            break
    if might_match:
        # Then we have to do the old slow way.
        for matchedLine in matchedLines:
            if matchedLine in target:
                # Do the split and write and so on.

但尝试做这样的事情真的很容易让自己聪明,这取决于你的数据是什么样的。