理解Python中的文件迭代

时间:2013-08-20 19:35:45

标签: python

我一直在尝试在Python中进行一些文本操作,并且遇到了很多问题,主要是由于对Python文件操作如何工作的基本误解,所以我希望能够清除它。

所以我想说我正在迭代一个名为“my.txt”的文本文件,它有以下内容:

3 10 7 8     
2 9 8 3  
4 1 4 2

我用来迭代文件的代码是:

file = open ("my.txt", 'r')
for line in file:
    print line`

我从教程中复制并粘贴了上面的代码。我知道它的作用,但我不知道它为什么会起作用,这让我很烦。我试图准确理解变量“line”在文件中的含义。它是数据类型(字符串?)还是其他东西。我的直觉告诉我每一行代表一个字符串然后可以被操纵(这是我想要的)但我也理解字符串在Python中是不可变的。

记忆在这一切中扮演什么角色,如果我的文件太大而无法融入内存,它还能运作吗?第[3]行允许我访问每行中的第四个元素吗? 如果我只想在第二行工作,我可以这样做:

if line == 2: 
for循环中的

值得注意的是,我对Python很新,并且来自C \ C ++背景(不习惯不可变字符串)。我知道我把一些问题压成了一个问题,但对一般主题的任何澄清都会有所帮助:)

5 个答案:

答案 0 :(得分:3)

line是一行文字,表示为字符串。字符串是不可变的,但这不是操纵它们的问题; all variables in Python are references, and assigning to a variable points the reference to a new object。 (在C ++中,您无法更改引用所在的位置。)对文件进行迭代会在行上进行迭代,因此在每次迭代时,line都会引用一个表示输入文件下一行的新字符串。

如果您熟悉range-based for loops或其他语言的每个结构,那就是Python for的工作方式。循环变量不是计数器;你做不到

if line == 2:

因为line不是该行的索引;这是线本身。你可以做到

for i, line in enumerate(f):
    if i == 2:
        do_stuff_with(line)
        break  # No need to load the rest of the file

请注意,file是内置的名称,因此将该名称用于您自己的变量是一个坏主意。

答案 1 :(得分:1)

在Python中,您可以直接遍历文件。执行此操作的最佳方法是使用with语句,如:

with open("myfile.txt") as f:
    for i in f:
        # do stuff to each line in the file

这些行是表示文件中每一行(由换行符分隔)的字符串。如果你只想在第二行操作,你可以这样做:

with open("myfile.txt") as f:
    list_of_file = list(f)
    second_line = list_of_file[2]

如果您想要访问第二行的一部分,可以按空格将其拆分为另一个列表,如下所示:

second_number_in_second_line = second_line.split()[1]

关于内存,直接遍历文件将其全部读入内存,然而,将其转换为list。如果您想在不这样做的情况下访问各个行,请使用itertools.islice

答案 2 :(得分:1)

在每次迭代中,line变量都填充了从文件中读取的后续行的内容。所以,你将拥有:

  第一次迭代中

“3 10 7 8”
  第二次迭代中的“2 9 8 3”
  等

要单独获取数字,请使用拆分方法:link

因此,将line2进行比较并不会产生任何影响。如果您想识别行号,可以尝试:

lineNumber = 0
for line in file:
  print line
  if lineNumber == 2:
    print "that was the second line!"
  lineNumber += 1

根据评论中的建议,您可以使用enumerate

来简化此操作
for lineNumber, line in enumerate(file):
  print line
    if lineNumber == 2:
      print "that was the second line!"

答案 3 :(得分:1)

假设您拥有相同的文件:

3 10 7 8\n     
2 9 8 3\n  
4 1 4 2\n

file methods

上有许多file object

在Python中,您可以按字符C样式读取文件:

with open('/tmp/test.txt', 'r') as fin:     # fin is a 'file object' 
    while True:
        ch=fin.read(1)
        if not ch:
            break
        print ch,                           # comma suppresses the CR

您可以将整个文件作为单个字符串读取:

with open('/tmp/test.txt', 'r') as fin:
    data=fin.read()
    print data    

作为枚举行:

with open('/tmp/test.txt', 'r') as fin:
    for i, line in enumerate(fin):
        print i, line    

作为字符串列表:

with open('/tmp/test.txt', 'r') as fin:
    data=fin.readlines()  

循环文件对象的习惯用语:

for line in fin:                 # 'fin' is a file object result of open
    print line

与:

同义
for line in fin.readline():
    print line

和类似:

for line in 'line 1\nline 2\nline 3'.splitlines():
    print line

一旦习惯了循环于某些元素的Python样式循环(或Perl,或Obj C或Java范围样式循环),就可以使用它们而不必考虑它。

如果您想要每个项目的索引 - 请使用enumerate

答案 4 :(得分:0)

您可以使用您显示的代码迭代任意大小的文件,并且不应消耗超出最长单行大小的任何大量内存。

至于它是如何工作的,你可以深入研究Python本身的源代码,以了解血腥细节。在更高的层次上,只要考虑Python中的文件对象的实现者选择将逐行迭代作为其类的一个特性来实现。

Python中的许多集合数据类型和I / O接口都实现了某种形式的迭代。因此for构造是Python中最常见的循环类型。您可以迭代列表,元组和集(按项),字符串(按字符),字典(按键),许多类(包括标准库中的那些类以及来自第三方的类)实现 “iterator (coding) protocol”以促进此类使用。