让我们一步一步来看看你的功能:def read_messages(file):
函数read_messages接受单个参数file;begin函数。在
^{pr2}$
让变量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是相同的,那么line.strip()将始终得到相同的结果)。所以。。。在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。你注意到了吗?嗯,恰好lambdas只能包含一个表达式,并且它们隐式返回该表达式。例如,lambda x: x + 1是一个接受单个参数x并返回x + 1的函数。在
现在,我们有三个新函数:map,filter,和all:map(f, list):接受一个函数f,并为list中的每个x调用{},创建另一个保存结果的列表。它相当于[ f(x) for x in list ]。在
filter(f, list):接受一个函数f,并在^{中创建一个新列表。对于list中的任何x,如果f(x)是{},那么{}将进入新列表。否则,将被丢弃。它相当于[ x for x in list if f(x) ]。在
all(list):获取一个列表,如果列表中的所有元素都是{},则返回{},否则返回{}。在
最后,string.whitespace是所有空白字符的列表。在
那么,这个新的结构可以用简单的英语说吗?当然!在Return a new list made up of each line in the file, with its trailing whitespace removed, if the line is not empty and not all characters in that line are whitespace characters.