每次添加文件而不添加标题行

AEA*_*AEA 0 python file stringio python-2.7

Bonjour Stack0verflow

我试图让这段代码将数据写入stored_output没有第1行(标题行)

我尝试过的:

with open(filenamex, 'rb') as currentx:
    current_data = currentx.read()
    ## because of my filesize I dont want to go through each line the the route shown below to remove the first line (title row)
    for counter, line in enumerate(current_data):
        if counter != 0:
            data.writeline(line)
    #stored_output.writelines(current_data)
Run Code Online (Sandbox Code Playgroud)

因为文件大小我不想做for循环(效率)

任何建设性的评论或代码片段将不胜感激.
谢谢AEA

Ash*_*ary 9

您可以next()在文件迭代器上使用跳过第一行,然后使用file.writelines以下内容编写其余内容:

with open(filenamex, 'rb') as currentx, open('foobar', 'w') as data:
    next(currentx)            #drop the first line
    data.writelines(currentx) #write rest of the content to `data`
Run Code Online (Sandbox Code Playgroud)

注意:file.read()如果要逐行读取文件,不要使用,只需遍历文件对象即可一次获取一行.


aba*_*ert 6

你第一个问题是currentx.read()返回一个巨大的字符串,所以遍历它遍历每个的字符在该字符串,而不是每个文件中的行.

您可以将文件作为一个巨大的字符串列表读入内存,如下所示:

current_data = list(currentx)
Run Code Online (Sandbox Code Playgroud)

但是,这几乎可以保证比一次遍历文件一样慢(因为你浪费时间为整个文件分配内存,而不是让Python选择合理大小的缓冲区)或立即处理整个文件(因为你在浪费时间分裂线路).换句话说,你通过这种方式获得了两个世界中最糟糕的一面.

所以,要么将它保持为线上的迭代器:

next(currentx) # skip a line
for line in currentx:
    # do something with each line
Run Code Online (Sandbox Code Playgroud)

...或将其保留为字符串并拆分第一行:

current_data = currentx.read()
first, _, rest = current_data.partition('\n')
# do something with rest
Run Code Online (Sandbox Code Playgroud)

如果事实证明一次读取和写入文件太慢(这很可能 - 它会在写入之前强制将早期块从任何缓存中移出,防止交错,并浪费时间分配内存),但是一行在一个时间太慢(这是不太可能,但并非不可能 - 搜索换行符,复制小字符串,并在Python中循环不是免费的,只是CPU时间比I/O时间便宜得那么多很少有事)?

您可以做的最好的事情是选择一个理想的块大小并自己进行无缓冲的读写操作,并且只有在找到第一个之前才浪费时间搜索换行符.

如果你可以假设第一行永远不会超过块大小,这很容易:

BLOCK_SIZE = 8192 # a usually-good default--but if it matters, test
with open(inpath, 'rb', 0) as infile, open(outpath, 'wb', 0) as outfile:
    buf = infile.read(BLOCK_SIZE)
    first, _, rest = buf.partition(b'\n')
    outfile.write(rest)
    while True:
        buf = infile.read(BLOCK_SIZE)
        if not but:
            break
        outfile.write(buf)
Run Code Online (Sandbox Code Playgroud)

如果我不止一次这样做,我会写一个块文件迭代器函数(或者,更好的是,寻找一个预先测试的配方 - 它们遍布ActiveState和邮件列表).