一次读取两行
有没有比下面这种方法更好的方式来每次从文件中读取两行内容呢?
with open(fn) as f:
for line in f:
try:
line2 = f.next()
except StopIteration:
line2 = ''
print line, line2 # or something more interesting
我现在用的是2.5.4版本。新版本有什么不同吗?
补充说明:有个被删除的回答提到,在Python 3中,你需要用next(f)来代替f.next()。还有打印方式也有变化。
3 个回答
1
对于小到中等大小的文件,
>>> data=open("file").readlines()
>>> for num,line in enumerate(data[::2]):
... print ''.join(data[num:num+2])
2
你可以用一个生成器来让它更清楚:
def read2(f):
for line in f:
try:
line2 = f.next()
except StopIteration:
line2 = ''
yield line, line2
with open(fn) as f:
for line1, line2 in read2(f):
print line1
print line2
18
import itertools
with open(fn) as f:
for line, line2 in itertools.izip_longest(f, f, fillvalue=''):
print line, line2
可惜的是,izip_longest
这个功能需要 Python 2.6 或更高版本;而 2.5 只有 izip
,如果文件 f
的行数是奇数的话,它会把最后一行截断。当然,提供一个等效功能的生成器是很简单的。
这里有一个更通用的“每次处理 N 行”的迭代器包装器:
def natatime(itr, fillvalue=None, n=2):
return itertools.izip_longest(*(iter(itr),)*n, fillvalue=fillvalue)
一般来说,使用 itertools
是最好的选择,但如果你坚持要自己实现的话,可以这样做:
def natatime_no_itertools(itr, fillvalue=None, n=2):
x = iter(itr)
for item in x:
yield (item,) + tuple(next(x, fillvalue) for _ in xrange(n-1))
在 2.5 版本中,我认为最好的方法其实不是用生成器,而是另一种基于 itertools 的解决方案:
def natatime_25(itr, fillvalue=None, n=2):
x = itertools.chain(iter(itr), (fillvalue,) * (n-1))
return itertools.izip(*(x,)*n)
(因为 2.5 版本没有内置的 next
,也缺少 izip_longest
)。