【问题标题】:Pythonic methods of returning the longest word in a string返回字符串中最长单词的 Pythonic 方法
【发布时间】:2014-10-27 07:50:37
【问题描述】:

我知道在字符串中查找最长的单词已被多次询问和回答,但我想知道以下方法之间的区别,以及为什么人们会使用方法 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

VS 方法 B

def LongestWord(sen): 
  x = max(sen.split(), key=len)
  return x

再次,我的目标是询问哪种方法会更稳定,因为缺少更好的词选择,以及为什么。如果您有自己的选择,请将其与您的解释一起发布。谢谢!

【问题讨论】:

  • 方法 A 使用了糟糕的变量名并且难以理解。方法 B 相当明显,利用了众所周知的内置函数。 A 在字符串上重复使用+=,这是低效的,并且可能调用len() 也超出必要。不过,在他们做同样的事情之前,这并不重要,但他们没有。 A 在其单词中不包含标点符号(例如,“you're”是一个非常好的词),B 包含所有标点符号(例如,句点通常不包含在单词长度中)。
  • 代码越少越好,除非难以理解。因为B 很容易理解,而A 不那么容易理解……但是minitech 对标点符号的处理是正确的。
  • 不要犹豫,使用更长的变量名。你不会浪费任何墨水:)
  • 请注意,Python 函数中的约定应以小写开头
  • @minitech,谢谢,非常彻底。 Precisley 我正在寻找的东西。另外,感谢您的提示!

标签: python string function string-length


【解决方案1】:

方法 B 远胜于远景。方法 A 令人困惑,所有嵌套的逻辑和简洁的变量名称。

[PEP 20]:

  • 美胜于丑。
  • 可读性很重要。
  • 如果实现难以解释,那就是个坏主意。

    $ python -c "import this"

【讨论】:

  • “平面比嵌套更好”我假设也是合适的。哈哈
【解决方案2】:

当我查看第二种方法时,我可以立即看到发生了什么——一个字符串在连续运行的空白处被拆分,然后返回最长的子字符串。

当我查看第一种方法时,需要做更多的工作才能弄清楚发生了什么。

关键是 python 提供了非常强大的实用程序来完成这些简单的任务——它使代码更容易编写、更容易阅读、更不容易出错等等。学习使用常用的习惯用法和函数来你的优势是(恕我直言)成为“pythonic”的本质

【讨论】:

  • 谢谢!我会进一步研究。
【解决方案3】:

首先,第二种方法可读性很强,而第一种则不然。显然,该方法(了解 max 方法)按照函数的名称执行。编写可读的代码是我最喜欢 Python 的部分。

其次,第一种方法负责定义单词是什么。部分

for c in sen:
  if c.isalpha():
    w += c

将使2spooky4me 比spookytoo 更短,因为LongestWord 不将单个整数字符计为单词(ex. '2'.isalpha() == False) 的一部分。对于使用此代码的人来说,这可能是意外的行为。

最后,第二个示例更优雅地使用了 Python 的内置方法(例如 max 的特性,而不仅仅是 len 和二元运算符),我认为这是该语言设计的一个重要目标。

【讨论】:

    【解决方案4】:

    有不同的原因。 最重要的是,作为软件开发人员,你必须使用最简单、最易理解的方式来编写函数。 方法 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
    

    【讨论】:

    • 我只想说,你的男人! timeit 将在未来的 pythonic 工作中派上用场。谢谢;)
    • 我会省略关于您的计时结果的最后一部分。这充其量只是轶事......记住Knuth:“过早的优化是万恶之源”。
    猜你喜欢
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多