请考虑以下代码:
f = open('file.txt')
for l in f:
k = l.strip() # Remove the newline character.
print(k)
f.close()
我想自动删除换行符。我知道我能做到:
for k in [l.strip() for l in f]:
print(k)
但这需要将f
的长度循环两次(并将整个内容加载到内存中)。我想知道是否还有像Pythonic这样的东西:
for lambda l: l.strip() in f:
print(l)
或者只是:
for l.strip() in f:
print(l)
当然,这些都不起作用。要了解如何将其应用于其他地方,以下是嵌套列表的示例:
d = [['hi'], ['hello'], ['howdy']]
for item in d:
item = item[0] # Get the nested item.
if item == 'hello':
print(item)
答案 0 :(得分:5)
您可以使用generator expression:
for k in (l.strip() for l in f):
print(k)
这与列表理解非常相似,不同之处在于它会懒惰地(逐个)生成项目,而不是一次性将它们全部收集到列表中。因此,我们一次只循环f
的长度,同时避免将所有内容全部转储到内存中。
答案 1 :(得分:3)
欢迎来到Python迭代器的世界:)
你对列表推导有正确的想法,除了你想要它延迟加载而不是首先在内存中建立整个列表(对于非常大的文件甚至可能是站不住脚的):使用生成器表达式< / strong>相反,它具有相同的语法,除了方括号被括号替换(如果它是函数的唯一参数,则可省略):
with open(filename) as f:
for l in (l.strip() for l in f.readlines()):
print(l)
来源:在the relevant Python Enhancement Proposal和official docs了解更多相关信息。
使用类似于LISP的语法来实现它的另一种功能方法是使用map
将函数应用于迭代器的每个元素 - 它不必是序列并假设您使用Python,这将涉及仅循环遍历所有行:
for l in map(lambda l: l.strip (), f):
print(l)
另外,f.readlines()
可能比仅仅循环f
更清晰,with
语句比自己调用f.close()
更加Pythonic。
答案 2 :(得分:0)
尚未测试但应该是正确的:重要的部分是使用replace
。在我看来,for循环是一种有效的方法,但是如果你想要一个衬里,请使用类似的东西:
no_new_lines = None
with open('path/to/file', 'rb') as file_content:
no_new_lines = file_content.read().replace('\r\n', '\n').replace('\n', '')
请注意“replace
”会复制要替换的内容。在内存很少的系统上打开一个巨大的文件会导致问题(MemoryError
)。无论如何,测试它,看看哪个更好。