Python为什么在此代码中两次使用open(filename)?

时间:2018-08-06 14:16:02

标签: python python-3.x

这是《机器学习in Action》第2章中的一段代码。 目标是将文件传输到matix。我不明白的是为什么我应该两次使用fr = open(filename)?

当我删除第二个open(filename)时,代码仅返回空白矩阵。我不知道为什么。

非常感谢您抽出宝贵的时间!

def file2matrix(filename):
    fr = open(filename)
    numberOfLines = len(fr.readlines())        
    returnMat = zeros((numberOfLines,3))       
    classLabelVector = []                       
    fr = open(filename)
    index = 0
    for line in fr.readlines():
        line = line.strip()
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector

3 个答案:

答案 0 :(得分:1)

它将读取文件两次:

  1. 首先读取所有行,然后对行进行计数并初始化矩阵:

    fr = open(filename)
    numberOfLines = len(fr.readlines())        
    returnMat = zeros((numberOfLines,3))
    
  2. 其次,它再次读取文件以填充矩阵:

    fr = open(filename)
    index = 0
    for line in fr.readlines():
        line = line.strip()
        ...
    

它需要再次打开文件,以便从头开始重新读取。

这不是有效的代码。由于fr.readlines()会读取整个文件,因此无需再次读取文件,而是将结果(行列表)存储在变量中,并在填充矩阵时重新使用。

完成文件处理后,还应该调用close()

答案 1 :(得分:1)

使用readlines函数时,它将所有行读入内存,并且在文件末尾,文件指针位于文件的末尾。

因此,如果您已经使用完后尝试重新读取行,由于文件指针位于末尾,它将从头到尾读取,因此为空白矩阵。

他们重新打开了文件,以便文件指针从头开始。这样做的另一种方法是filevariable.seek(0),它将文件指针移回起点,您应该能够再次使用读取行。

要注意的一件事是,readlines会将整个文件读入内存,如果您有一个庞大的文件,则应使用for循环并使用readline一次读取一行。

答案 2 :(得分:0)

现在建议在处理文件时始终使用上下文管理器。请尝试以下操作,它应该与您要寻找的非常接近。

def file2matrix(filename):
    with open(filename, "r") as fr:
        returnMat = zeros((len(fr.readlines,3))
        classLabelVector = [] 
        index = 0
        for line in fr:
            line = line.strip()
            listFromLine = line.split('\t')
            returnMat[index,:] = listFromLine[0:3]
            classLabelVector.append(int(listFromLine[-1]))
            index += 1
    return returnMat,classLabelVector