在字符串中返回最长单词的Pythonic方法
我知道在字符串中找出最长单词这个问题已经被问过很多次了,但我想了解一下以下两种方法之间的区别,以及为什么会选择方法A而不是方法B,或者反过来。
方法A
def LongestWord(sen):
lw = ''
w = ''
for c in sen:
if c.isalpha():
w += c
else:
if len(w) > len(lw):
lw = w
w = ''
if len(w) > len(lw):
lw = w
return lw
与方法B对比
def LongestWord(sen):
x = max(sen.split(), key=len)
return x
再说一次,我的目标是想知道哪种方法会更稳定,换句话说,就是哪种方法更可靠。如果你有自己的其他方法,也请分享出来并解释一下。谢谢!
4 个回答
当我看到第二种方法时,我立刻就明白发生了什么——它把字符串按照连续的空格分开,然后返回最长的那一段。
而第一种方法就没那么简单了,得花更多的时间去弄明白它在做什么。
关键是,Python提供了非常强大的工具来处理这些简单的任务——这让代码更容易写,更容易读,出错的可能性也更小等等。学会利用常见的写法和函数对你有利,我认为这就是“Python风格”的精髓。
首先,第二种方法的代码很容易理解,而第一种方法就不太容易。第二种方法显然(如果你知道max这个方法的话)做的事情和函数的名字是一样的。写出易读的代码是我最喜欢Python的一部分。
其次,第一种方法自己定义了什么是一个单词。那段代码
for c in sen:
if c.isalpha():
w += c
会让 2spooky4me
比 spookytoo
短,因为 LongestWord
不把单个数字字符算作单词的一部分 (例如 '2'.isalpha() == False)
。这可能会让使用这段代码的人感到意外。
最后,第二个例子更优雅地使用了Python内置的方法(例如,使用max的特性,而不仅仅是len和二元运算符),我认为这是这个语言设计的一个重要目标。
方法B明显要好得多。方法A让人很困惑,因为里面有很多复杂的逻辑和简短的变量名。
[PEP 20]:
- 美观比丑陋更好。
- 可读性很重要。
如果实现起来很难解释,那就是个坏主意。
$ python -c "import this"
有很多原因。最重要的一点是,作为一个软件开发者,你必须用最简单、最容易理解的方式来写函数。
方法B简洁明了,容易理解。而方法A就太复杂了,光是看名字就很难知道它到底在干什么。
这就引出了另一个问题:代码如果太难读,就很难调试。方法B看起来是对的,没问题。方法A呢?理解起来就很困难。我们可以写测试来检查这两个函数是否都能正常工作(而且我们应该这么做),但如果某个函数出了问题,调试方法B会比调试方法A简单得多。
最后,方法B的速度快了10倍。
if __name__ == '__main__':
import timeit
print(timeit.timeit("LongestWordA('hello this is just an example')", number=1000, setup="from __main__ import LongestWordA"))
print(timeit.timeit("LongestWordB('hello this is just an example')", number=1000, setup="from __main__ import LongestWordB"))
# LongestWordA 0.013688346021808684
# LongestWordB 0.004950157948769629