write - python3 read file




如何在python中逐行讀取大文件 (7)

我想遍歷整個文件的每一行。 一種方法是讀取整個文件,將其保存到列表中,然後轉到感興趣的行。 這種方法使用了大量的內存,所以我正在尋找替代方案。

我的代碼到目前為止:

for each_line in fileinput.input(input_file):
    do_something(each_line)

    for each_line_again in fileinput.input(input_file):
        do_something(each_line_again)

執行此代碼會給出錯誤消息: device active

有什麼建議麼?

編輯:目的是計算成對的字符串相似性,這意味著文件中的每一行,我想要計算每隔一行的Levenshtein距離。


剝離換行符:

with open(file_path, 'rU') as f:
    for line_terminated in f:
        line = line_terminated.rstrip('\n')
        ...

對於通用換行支持 ,無論文件中的終結符'\r''\n'還是'\r\n' ,所有文本文件行似乎都以'\n'結尾。

編輯 -指定通用換行支持:

  • Unix上的Python 2 - open(file_path, mode='rU') - 必需[謝謝@Dave ]
  • Windows上的Python 2 - open(file_path, mode='rU') - 可選
  • Python 3 - open(file_path, newline=None) - 可選

newline參數僅在Python 3中受支持,並且默認為None 。 在所有情況下, mode參數默認為'r'U在Python 3中已被棄用。在Windows上的Python 2中,某些其他機制似乎將\r\n\n

文檔:

為了保留本地行結束符:

with open(file_path, 'rb') as f:
    with line_native_terminated in f:
        ...

二進制模式仍然可以將文件解析為包含in行。 每行都會有文件中的任何終止符。

感謝@katrielalex的answer ,Python的open() doc和iPython實驗。


Katrielalex提供了打開和讀取一個文件的方式。

但是,您的算法執行的方式會為文件的每一行讀取整個文件。 這意味著如果N是文件中行的數量,則讀取文件的總量以及計算Levenshtein距離將被執行N * N。 由於您關心的是文件大小,並且不想將其保存在內存中,所以我擔心產生的二次運行時間 。 你的算法在O(n ^ 2)類算法中,通常可以通過專門化來改進。

我懷疑你已經知道內存與運行時間的權衡,但也許你想研究是否有一種有效的方法來並行計算多個Levenshtein距離。 如果是這樣,在這里分享你的解決方案會很有趣。

你的文件有多少行,以及你的算法需要運行什麼樣的機器(mem和cpu power)以及容忍的運行時間是多少?

代碼如下所示:

with f_outer as open(input_file, 'r'):
    for line_outer in f_outer:
        with f_inner as open(input_file, 'r'):
            for line_inner in f_inner:
                compute_distance(line_outer, line_inner)

但問題是如何存儲距離(矩陣?),並且您是否可以獲得準備處理的outer_line或緩存某些中間結果以供重用等優點。


我強烈建議不要使用默認文件加載,因為它非常慢。 您應該查看numpy函數和IOpro函數(例如numpy.loadtxt())。

http://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

https://store.continuum.io/cshop/iopro/

然後你可以把你的成對操作分成幾塊:

import numpy as np
import math

lines_total = n    
similarity = np.zeros(n,n)
lines_per_chunk = m
n_chunks = math.ceil(float(n)/m)
for i in xrange(n_chunks):
    for j in xrange(n_chunks):
        chunk_i = (function of your choice to read lines i*lines_per_chunk to (i+1)*lines_per_chunk)
        chunk_j = (function of your choice to read lines j*lines_per_chunk to (j+1)*lines_per_chunk)
        similarity[i*lines_per_chunk:(i+1)*lines_per_chunk,
                   j*lines_per_chunk:(j+1)*lines_per_chunk] = fast_operation(chunk_i, chunk_j) 

將數據加載到數據塊中,然後對其執行矩陣操作,要比逐元素地完成數據快得多!


按照排名順序的兩種高效存儲方式(第一種最好) -

  1. 使用with - 來自python 2.5及以上版本
  2. 如果您真的想控制閱讀yield ,可以使用yield

with

with閱讀大文件是一種很好且高效的pythonic方式。 優點 - 1)文件對象退出執行塊後自動關閉。 2) with塊內的異常處理。 3)循環內存循環遍歷f文件對象。 內部它可以緩衝IO(以優化昂貴的IO操作)和內存管理。

with open("x.txt") as f:
    for line in f:
        do something with data

2.使用yield

有時候可能需要對每次迭代中需要讀取的內容進行更細粒度的控制。 在這種情況下使用它和yield 。 請注意,在這種方法中,顯式需要在最後關閉文件。

def readInChunks(fileObj, chunkSize=2048):
    """
    Lazy function to read a file piece by piece.
    Default chunk size: 2kB.
    """
    while True:
        data = fileObj.read(chunkSize)
        if not data:
            break
        yield data

f = open('bigFile')
for chuck in readInChunks(f):
    do_something(chunk)
f.close()

陷阱和為了完整起見 - 下面的方法對於閱讀大文件來說並不是很好或不夠優雅,但請閱讀以獲得圓潤的理解。

在Python中,從文件中讀取行的最常用方法是執行以下操作:

for line in open('myfile','r').readlines():
    do_something(line)

但是,當完成這些時, readlines()函數(同樣適用於read()函數)將整個文件加載到內存中,然後遍歷它。 對於大文件,稍好的方法(前面提到的兩種方法最好)是使用fileinput模塊,如下所示:

import fileinput

for line in fileinput.input(['myfile']):
    do_something(line)

fileinput.input()調用順序地讀取行,但是在讀取之後不會將它們保存在內存中,或者甚至只是這樣,因為python中的file是可迭代的。

參考

  1. Python語句

逐行讀取大文件的最佳方法是使用python 枚舉函數

with open(file_name, "rU") as read_file:
    for i, row in enumerate(read_file, 1):
        #do something
        #i in line of that line
        #row containts all data of that line

這是在python中讀取文件的一種可能方式:

f = open(input_file)
for line in f:
    do_stuff(line)
f.close()

它沒有分配一個完整的列表。 它遍歷線。


#Using a text file for the example
with open("yourFile.txt","r") as f:
    text = f.readlines()
for line in text:
    print line
  • 打開你的文件閱讀(r)
  • 閱讀整個文件並將每行保存到列表 (文本)
  • 循環顯示每行的列表。

例如,如果您想要檢查長度大於10的特定行,請使用您已有的功能。

for line in text:
    if len(line) > 10:
        print line




file-read