我想打印出文件的前10行,避免读取任何额外的行。如何在不读取整个文件的情况下使用列表推导来做到这一点?
我知道我可以这样做代码:
N = 10
with open(path,'rb') as f_in:
for line in f_in:
print line.strip()
N -= 1
if N == 0:
break
但我认为列表理解更合适:
with open(path,'rb') as f_in:
[print line for i, line in enumerate(f_in) if i<N]
然而,由于打印声明,这不起作用,所以我最终得到了这个烂摊子:
with open(path,'rb') as f_in:
lines = [line.strip() for i, line in enumerate(f_in) if i<N]
for line in lines:
print line
我的问题的真正意义在于,当我= = N而不是不必要地继续并且只过滤掉额外的行时,你如何让列表理解停止?
有没有办法限制列表理解将进入迭代器的距离?是否有适当的方式从列表理解中打印出来?我对python很新,所以我试图学习如何以正确的方式做事,而不仅仅是我能想到的第一种方式。我想以pythonic的方式写这个。
答案 0 :(得分:3)
当i == N而不是时,你如何让列表理解停止? 不必要的继续,只过滤掉额外的线? 有没有办法限制列表理解将进入迭代器的距离?
您可以使用itertools.islice
迭代一个可迭代的片段:
from itertools import islice
with open(path,'rb') as f_in:
for line in islice(f_in, N):
print line.strip()
实际上,您可以指定要生成的第一行的索引,甚至是步骤(如列表或字符串切片)。
请注意,如果您实际上不需要列表,则不应使用list-comprehension,因为它会消耗内存(在您的情况下,您将文件的所有内容保留在内存中,如果文件中的文件内容可能会很糟糕很大)。 如果你只想迭代一次使用生成器表达式:
lines = (line.strip() for line in f_in)
(是的,您只需使用[]
更改()
)。
这避免了在执行时构建整个列表。
是否有合适的方法从列表理解中打印出来?
没有
在python2中print
是一个语句,因此它不能出现在表达式中
在python3中你可以调用print
,因为它是一个函数,但它是非常糟糕的主意。
列表推导有一个特定的目的:从给定的可迭代构建列表。 你扔掉了这个列表,从而打败了那个语法的整个目的。
由于这个原因,在列表理解中不支持“打破”循环。如果您的代码非常复杂,需要break
,那么最好使用明确的for
循环编写代码。
如果您尝试执行调用map
:
map(lambda line: print line, lines)
假设可以在print
lambda
这甚至在python3中失败(它不会打印任何东西)。
如果你想编写好的python代码,首要的规则是遵循语言设计: 不要混合表达式和语句,也就是说:使用表达式返回值,不要滥用它们来产生副作用。
答案 1 :(得分:1)
您还可以在所需的行范围内调用文件对象上的next():
lines = [f_in.next() for x in range(10)]
这将为您提供前十行。
如果要在文件开头跳过标题或其他行,则使用next()
会很有用。每次在文件对象上调用next时,都将移动到文件的下一行。
如果您想打印行的内容,可以使用join()
:
print "".join(lines)