我创建了以下函数来从文件中提取数据.它工作正常,但对于较大的文件来说速度很慢.
def get_data(file,indexes,data_start,sieve_first = is_float):
file_list = list(file)
for i in indexes:
d_line = i+data_start
for line in file_list[d_line:]:
if sieve_first(line.strip().split(',')[0]):
yield file_list[d_line].strip()
d_line += 1
else:
break
def is_float(f):
try:
float(str(f))
except:
return False
else:
return True
with open('my_data') as f:
data = get_data(f,index_list,3)
line 1234567: # <-- INDEX
line 1234568: # +1
line 1234569: # +2
line 1234570: 8,17.0,23,6487.6
line 1234571: 8,6487.6
line 1234572: 8,6487.6
line 1234572:
line 1234572:
line 1234572:
通过上面的例子,将产生1234570到1234572行.
>首先是它将整个文件读入内存;我这样做,所以我可以使用行索引来解析数据.
>其次是文件中的相同行重复多次 – 这对于大文件来说非常昂贵.
我试图使用迭代器一次性完成文件,但却无法破解它.有什么建议?
最佳答案
如果你只需要文件的一小部分,我会使用itertools.islice.这个函数不会存储任何数据,而是存储你想要的数据.
这是一个例子:
from itertools import islice
def yield_specific_lines_from_file(filename,start,stop):
with open(filename,'rb') as ifile:
for line in islice(ifile,stop):
yield line
lines = list(yield_specific_lines_from_file('test.txt',10,20))
如果您使用Python 3.3或更高版本,您还可以使用yield from
语句简化此操作:
from itertools import islice
def yield_specific_lines_from_file(filename,'rb') as ifile:
yield from islice(ifile,stop)
lines = list(yield_specific_lines_from_file('test.txt',20))
这不会缓存您已经从文件中读取的行.如果您想这样做,我建议您将所有读取行存储在字典中,并将行号作为键,并且只在需要时从文件中提取数据.