让我们一步一步看你的功能:
def read_messages(file):
函数read_messages接受一个参数file;开始函数。
message = []
让变量message 为空列表([])。
for line in file:
对于file 中的每一行,让变量line 成为这样的一行。
new_line = line.strip()
让变量new_line 成为line 变量,去掉开头和结尾的所有空格。
message.append(new_line)
将new_line 附加到message。
return message
返回变量message;结束函数。
算法是对的(为什么不说?),但可以简化,首先是模式……
x = []
for ...:
something = ...
x.append(something)
doSomething(x) # Can be `return` too
可以简化为列表理解。列表推导式是一种以简单易读的表达式构造列表的方法,无需费力地创建、添加和返回列表。根据之前的模式,您可以执行类似...
doSomething([ something for ... ])
这和上面的模式是一样的!现在,应用于您的代码:
return [ ??? for line in file ]
我们应该放什么而不是????好吧,你当然必须放上计算new_line(line.strip())的代码!这是因为new_line 可以作为line.strip() 的同义词,因为line.strip() 没有副作用(line.strip() 将始终给出相同的结果,无论何时调用它,因为line是一样的)。所以...
return [ line.strip() for line in file ]
您可以使用它,或者如果您不想在开头丢失空格,那么...
return [ line.rstrip() for line in file ]
rstrip() 与strip() 的作用相同,只是它不删除字符串开头的空格。
所以,你的函数变成了……
def read_messages(file):
return [ line.rstrip() for line in file ]
这都是根据你的要求,但让我们再做一些优化!
如果任何一行是空的,或者只包含空格,您希望该行进入列表吗?至少我不会。那么你将如何解决这个问题?我会采用列表理解,并过滤掉所有空行,或者那些仅由空格组成的行。所以,事情就变成了……
import string
def read_messages(file):
return filter(lambda x: not all(map(lambda y: y in string.whitespace, x)), [ line.rstrip() for line in file ])
现在,那是什么?首先,lambda 就像一个可以在任何地方声明为表达式的函数。格式为lambda parameters...: return_value。你注意到return_value 的东西了吗?好吧,碰巧 lambda 只能包含一个表达式,并且它们隐式返回该表达式。因此,例如,lambda x: x + 1 是一个接受单个参数 x 并返回 x + 1 的函数。
现在,我们有了三个新函数:map、filter 和 all:
-
map(f, list):接受一个函数f 并为list 中的每个x 调用f(x),创建另一个列表来保存其结果。相当于[ f(x) for x in list ]。
-
filter(f, list):采用函数f 并从list 中创建一个新列表。对于list 中的任何x,如果f(x) 是True,则x 进入新列表。否则,它被丢弃。相当于[ x for x in list if f(x) ]。
-
all(list):获取一个列表,如果列表中的所有元素都是True,则返回True,否则返回False。
最后,string.whitespace 是所有空白字符的列表。
那么,这个新结构可以用简单的英语来表达吗?当然!
如果该行不为空且该行中并非所有字符都是空白字符,则返回由文件中的每一行组成的新列表,并删除其尾随空格。