关于python的两个简单问题

2 python file

我有2个关于python的简单问题:

1.如何在python中获取文件的行数?

2.如何轻松地将文件对象中的位置定位到最后一行?

nos*_*klo 8

行只是由换行符char分隔的数据'\n'.

1)由于行是可变长度的,你必须读取整个文件以知道换行符的位置,这样你就可以计算多少行:

count = 0
for line in open('myfile'):
    count += 1
print count, line # it will be the last line
Run Code Online (Sandbox Code Playgroud)

2)从文件末尾读取一个块是查找最后一个换行符char的最快方法.

def seek_newline_backwards(file_obj, eol_char='\n', buffer_size=200):
    if not file_obj.tell(): return # already in beginning of file
    # All lines end with \n, including the last one, so assuming we are just 
    # after one end of line char
    file_obj.seek(-1, os.SEEK_CUR)
    while file_obj.tell():
        ammount = min(buffer_size, file_obj.tell())
        file_obj.seek(-ammount, os.SEEK_CUR)
        data = file_obj.read(ammount)
        eol_pos = data.rfind(eol_char)
        if eol_pos != -1:
            file_obj.seek(eol_pos - len(data) + 1, os.SEEK_CUR)
            break
        file_obj.seek(-len(data), os.SEEK_CUR)
Run Code Online (Sandbox Code Playgroud)

您可以这样使用:

f = open('some_file.txt')
f.seek(0, os.SEEK_END)
seek_newline_backwards(f)
print f.tell(), repr(f.readline())
Run Code Online (Sandbox Code Playgroud)


Cha*_*tin 7

我们不要忘记

f = open("myfile.txt")
lines = f.readlines()

numlines = len(lines)
lastline = lines[-1]
Run Code Online (Sandbox Code Playgroud)

注意:这将以内容的形式读取内存中的整个文件.在文件非常大的情况下请记住这一点.

  • 是的,而且?当我在8K的内存中编写业务应用程序时,我可能会关心. (4认同)
  • @nosklo:然后你会改变你的算法.你的观点是什么?对于地球上的每个问题,都没有"一刀切"的最佳解决方案.为了简单和明确,+1. (3认同)
  • @Charlie - 我必须在这里同意nosklo.假设文件总是适合内存,那种懒惰的编程很容易导致漏洞和不稳定. (3认同)
  • @noskio,"过早优化是所有邪恶的根源." 我的意思是,如果文件被加密怎么办?如果它是二进制数据怎么办?至于那时我是否打了虚拟内存,好吧,是的,这就是它的用途.奇怪的是,通常交换器比文件I/O更有效. (3认同)
  • 它也会立即将整个文件读入内存. (2认同)

Bri*_*ian 5

最简单的方法就是文件读入到内存中.例如:

f = open('filename.txt')
lines = f.readlines()
num_lines = len(lines)
last_line = lines[-1]
Run Code Online (Sandbox Code Playgroud)

但是对于大文件,这可能会占用大量内存,因为整个文件都会加载到RAM中.另一种方法是逐行遍历文件.例如:

f = open('filename.txt')
num_lines = sum(1 for line in f)
Run Code Online (Sandbox Code Playgroud)

这样效率更高,因为它不会将整个文件加载到内存中,而只能一次查看一行.如果你想要最后一行,你可以在迭代时跟踪这些行,并通过以下方式获得两个答案:

f = open('filename.txt')
count=0
last_line = None
for line in f:
    num_lines += 1
    last_line = line
print "There were %d lines.  The last was: %s" % (num_lines, last_line)
Run Code Online (Sandbox Code Playgroud)

如果您只需要最后一行,最后一个可能的改进是从文件末尾开始,然后向后搜索,直到找到换行符. 这是一个有一些代码执行此操作的问题.如果你同时需要两个行数,那么除了迭代文件中的所有行之外别无选择.

  • 容易并不意味着快速或高效:-p (2认同)