我在python中相对较新,正在研究C语言。因为我在python中看到了许多我不知道的新函数,所以我想知道是否有一个函数可以从python中的文件请求10000行。
如果存在这种功能,我会期待这样的事情:
lines = get_10000_lines(file_pointer)
python是否有内置功能,或者我可以为此下载任何模块吗? 如果没有,我该如何做到这一点是最简单的方法。我需要分析一个巨大的文件,所以我想读取10000行并分析每次以节省内存。
感谢您的帮助!
答案 0 :(得分:22)
f.readlines()返回一个包含文件中所有数据行的列表。如果给定一个可选的参数sizehint,它会从文件读取多个字节,并且足以完成一行,并从中返回行。这通常用于允许按行有效读取大文件,但无需将整个文件加载到内存中。只返回完整的行。
来自the docs。
这并不是你要求的,因为这限制了读取的字节数而不是读取的行数,但我认为这是你想要做的事情。
答案 1 :(得分:21)
from itertools import islice
with open(filename) as f:
first10000 = islice(f, 10000)
这会将first10000
设置为可迭代对象,即您可以使用
for x in first10000:
do_something_with(x)
如果您需要列表,请改为list(islice(f, 10000))
。
当文件包含少于10k行时,这将返回文件中的所有行,没有填充(与基于range
的解决方案不同)。当以块的形式读取文件时,结果中的< 10000行会发出EOF信号:
with open(filename) as f:
while True:
next10k = list(islice(f, 10000)) # need list to do len, 3 lines down
for ln in next10k:
process(ln)
if len(next10k) < 10000:
break
答案 2 :(得分:5)
你真的关心你一次有多少行吗?通常最有意义的是逐行迭代文件对象:
f = open('myfile.txt', 'r')
for line in f:
print line
python文档表明这是处理文件的首选方法:
读取行的另一种方法是遍历文件对象。这样可以节省内存,速度快,并且可以使代码更简单。
有关示例,请参阅python docs。
答案 3 :(得分:3)
只需打开文件,告诉Python读取一行10,000次。
lines = None
with open('<filename>') as file:
lines = (file.readline() for i in range(10000))
答案 4 :(得分:3)
你确定文件对于内存来说太大了吗?
由于函数调用有开销(即调用相同的函数10000次很慢)并且内存很便宜,我建议一次读取所有行,然后切换到结果列表中。如果您想稍后处理下一个10000,这当然是最快的方式 - 它们将立即为您做好准备。
with open("filename") as f:
lines = f.readlines()
indices = range(0, len(lines), 10000) + [len(lines)]
for start, stop in zip(indices, indices[1:]):
do_stuff_with(lines[start:stop])
当然,如果文件不适合空闲内存,那么这将无效。如果是这样的话,我会选择ChipJust's answer。您甚至可以使用readlines
sizehint,tell
和seek
创建一个追求目标的功能,如果这很重要的话,它将在10000条线路上“归属”。
答案 5 :(得分:3)
f = open('myfile.txt', 'r')
while True:
bytes_lines = f.readlines(10000) # read no more than 10000 bytes
if not bytes_lines: break # stop looping if no lines read
for line in bytes_lines:
text = line.decode("knownencoding") # text will be a unicode object
一次读取大量文本然后处理它会更快。这会读取大量文本,然后将其拆分为多行。这节省了读取。它也只会给你完整的行,所以你不需要处理连接行的存根。
进行测试以确保从已经存在的文件中读取不会引发异常。
答案 6 :(得分:3)
没有任何功能可以按照您的意愿运行。你可以轻松地写一个,但你可能不会更好。例如,如果您获得这里显示的许多解决方案的行列表,那么您必须分别分析每一行:
def get_10000_lines(f):
while True:
chunk = list(itertools.islice(f, 10000))
if not chunk:
break
yield chunk
如果你这样做,你也可以一次只读取一行文件,并分析每个字符串。无论如何,文件I / O都将被缓冲:
for line in f:
analyze_the_line(line)
如果你想要一个包含10,000行的字符串,那么你将单独阅读每一行并将它们连接在一起:
for chunk in get_10000_lines(f):
str_10k = "".join(chunk)
analyze_a_bunch(str_10k)
现在你正在做很多分配和连接字符串的工作,这可能不值得。
如果你可以对部分行进行分析,那么最好是你可以用1Mb块读取文件:
while True:
chunk = f.read(1000000)
if not chunk:
break
analyze_a_bunch(chunk)
答案 7 :(得分:3)
从几个other solutions中抽取,但添加了一个扭曲......
>>> with open('lines.txt', 'r') as lines:
... chunks = iter(lambda: list(itertools.islice(lines, 7)), [])
... for chunk in chunks:
... print chunk
...
['0\n', '1\n', '2\n', '3\n', '4\n', '5\n', '6\n']
['7\n', '8\n', '9\n', '10\n', '11\n', '12\n', '13\n']
['14\n', '15\n', '16\n', '17\n', '18\n', '19\n', '20\n']
['21\n', '22\n', '23\n', '24\n', '25\n', '26\n', '27\n']
['28\n', '29\n', '30\n', '31\n', '32\n', '33\n', '34\n']
['35\n', '36\n', '37\n', '38\n', '39\n', '40\n', '41\n']
['42\n', '43\n', '44\n', '45\n', '46\n', '47\n', '48\n']
['49\n', '50\n', '51\n', '52\n', '53\n', '54\n', '55\n']
['56\n', '57\n', '58\n', '59\n', '60\n', '61\n', '62\n']
['63\n', '64\n', '65\n', '66\n', '67\n', '68\n', '69\n']
['70\n', '71\n', '72\n', '73\n', '74\n', '75\n', '76\n']
['77\n', '78\n', '79\n', '80\n', '81\n', '82\n', '83\n']
['84\n', '85\n', '86\n', '87\n', '88\n', '89\n', '90\n']
['91\n', '92\n', '93\n', '94\n', '95\n', '96\n', '97\n']
['98\n', '99\n']
但在这里我必须承认,正如其他人所说,只要你不需要完全 10000行(或10000),使用带有字节提示的readlines
就会快一点每次都行)。但是,我不相信这是因为它的读取次数较少。 readlines
docstring说“重复调用readline()并返回如此读取的行列表。”所以我认为速度增益来自于削减一些少量的迭代器开销。定义(使用Marcin的代码):
def do_nothing_islice(filename, nlines):
with open(filename, 'r') as lines:
chunks = iter(lambda: list(itertools.islice(lines, nlines)), [])
for chunk in chunks:
chunk
def do_nothing_readlines(filename, nbytes):
with open(filename, 'r') as lines:
while True:
bytes_lines = lines.readlines(nbytes)
if not bytes_lines:
break
bytes_lines
试验:
>>> %timeit do_nothing_islice('lines.txt', 1000)
10 loops, best of 3: 63.6 ms per loop
>>> %timeit do_nothing_readlines('lines.txt', 7000) # 7-byte lines, ish
10 loops, best of 3: 56.8 ms per loop
>>> %timeit do_nothing_islice('lines.txt', 10000)
10 loops, best of 3: 58.4 ms per loop
>>> %timeit do_nothing_readlines('lines.txt', 70000) # 7-byte lines, ish
10 loops, best of 3: 50.7 ms per loop
>>> %timeit do_nothing_islice('lines.txt', 100000)
10 loops, best of 3: 76.1 ms per loop
>>> %timeit do_nothing_readlines('lines.txt', 700000) # 7-byte lines, ish
10 loops, best of 3: 70.1 ms per loop
在平均线长7(逐行打印0 - > 1000000)的文件上,使用带有大小提示的readlines
会更快一点。但只是一点点。还要注意奇怪的缩放 - 我不明白那里发生了什么。