【问题标题】:Appending files to each other without adding the title row each time将文件彼此附加而不每次都添加标题行
【发布时间】:2013-11-12 04:49:32
【问题描述】:

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)

由于文件大小我不想做一个 for 循环(效率)

任何建设性的 cmets 或代码 sn-ps 将不胜感激。
感谢 AEA

【问题讨论】:

  • 我觉得因为文件比较大,其实循环遍历是个好主意,不然会占满你的内存。
  • 另外,按照你的做法,current_data 是一个巨大的字符串,所以enumerate(current_data) 给出了每个字符的索引和值,而不是每个线。如果您真的想将整个文件以行的形式读入内存(您可能不会),请执行 current_data = currentx.read().splitlines() 或者更好的是 current_data = list(currentx)
  • @aIKid 感谢您的评论,我将其存储在内存中。否则我们将执行一个文件写入很多次。内存对我来说不是问题。
  • hcwhsa的回答彻底解决了问题,看看吧。
  • @abarnert 我按顺序打开文件并按顺序附加它们。我不需要以任何方式读取或处理数据。你会建议一种替代方法吗?谢谢

标签: python file python-2.7 stringio


【解决方案1】:

您可以在文件迭代器上使用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`

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

【讨论】:

  • 不知道我们能做到这一点.. 很棒的解决方案!
  • 当你得到两个很棒的答案时该怎么办,我已经使用了这个解决方案,但我确实喜欢 abernets 对不同效率方式的详细描述。谢谢:)
【解决方案2】:

您的第一个问题是 currentx.read() 返回一个巨大的字符串,因此循环遍历该字符串中的每个 字符,而不是文件中的每一行。

你可以像这样将一个文件作为一个巨大的字符串列表读入内存:

current_data = list(currentx)

但是,这几乎可以保证比一次遍历文件一行要慢(因为您浪费时间为整个文件分配内存,而不是让 Python 选择一个合理大小的缓冲区)或处理整个文件一次(因为你在浪费时间分割线)。换句话说,这样一来,两全其美。

所以,要么将其作为迭代器保留在行上:

next(currentx) # skip a line
for line in currentx:
    # do something with each line

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

current_data = currentx.read()
first, _, rest = current_data.partition('\n')
# do something with rest

如果事实证明一次读取和写入文件太慢怎么办(这很可能——它会在写入之前将早期块强制从任何缓存中取出,防止交错,并浪费时间分配内存),但是一次一行太慢了(这不太可能,但并非不可能——在 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)

如果我要多次这样做,我会编写一个块文件迭代器函数(或者,更好的是,寻找一个预先测试过的配方——它们都在 ActiveState 和邮件列表中)。

【讨论】:

  • 我想确保我感谢您的回答,我接受了另一个,因为它是我使用的那个。但我真的很欣赏这个答案的一些内容。谢谢:)
猜你喜欢
  • 2013-11-10
  • 1970-01-01
  • 2013-11-29
  • 2015-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
相关资源
最近更新 更多