【问题标题】:Faster and more consise way to reverse sentences in a string?更快更简洁的方法来反转字符串中的句子?
【发布时间】:2014-04-02 07:13:01
【问题描述】:

好的,我正在寻找一种以快速简洁的方式反转字符串中的句子的方法。

例如,如果我想转换““一二三。四五六。”改为“三二一。六五四。”

这是我幼稚的做法:

def reverse_sentences(str):
 newlist=str.split(".")   
 newstr=''
 for s in newlist[0:-1]:
   words=s.split()
   words=words[::-1]
   words[0]=words[0][0].upper()+words[0][1:]
   words[-1]=words[-1][0].lower()+words[-1][1:]
   for e in range(len(words)):
      words[e].strip()
      if words[e] != words[-1]:
           newstr+=words[e]+" "
      else:
           newstr+=words[e]
   newstr+=". "
 return newstr

任何更快、更 Pythonic 的方式来做到这一点,例如列出理解和东西。

【问题讨论】:

  • 如果输入是One, two three.怎么办?你如何处理,
  • 不确定,假设只存在句点而不存在逗号。如果有人能准确地弄清楚这将是一个有趣的解决方案。

标签: python string algorithm


【解决方案1】:

这是一个使用列表理解切片str.join的长单行:

In [79]: t="One two three. Four five six."

In [80]: ' '.join(' '.join(sentence.lower().split()[::-1]).capitalize()+'.'
    ...:                              for sentence in t.split('.')[:-1])
Out[80]: 'Three two one. Six five four.'

【讨论】:

  • ? 这当然是“更简洁”,这是我们所要求的。它似乎没有更快(请参阅我的回答)或更 Pythonic(请参阅PEP 20),但我确实喜欢您的函数式方法。
  • @Johnsyweb 是的,它并不快,只是为了好玩;)
【解决方案2】:

我可能会使用generator expressions(对于lazy evaluation)写这样的东西:

def reverse_sentences(text):
    sentences = text.split('.')
    reversed_words = (reversed(words.split()) for words in sentences)
    rejoined_words = (' '.join(words) for words in reversed_words)
    capitalized_sentences = (sentence.capitalize() for sentence in rejoined_words)
    return '. '.join(capitalized_sentences)

reverse_sentences("One two three. Four five six.")

与“单行”相比,我更喜欢此功能,因为它更易于维护(例如,您是否希望添加标点符号处理或strip-ping 空格)。

将其分解为其组成部分(使用list comprehensions 进行说明):

In [1]: text = "One two three. Four five six."

In [2]: text
Out[2]: 'One two three. Four five six.'

In [3]: sentences = text.split('.')

In [4]: sentences
Out[4]: ['One two three', ' Four five six', '']

In [5]: reversed_words = [words.split()[::-1] for words in sentences]

In [6]: reversed_words
Out[6]: [['three', 'two', 'One'], ['six', 'five', 'Four'], []]

In [7]: rejoined_words= [' '.join(words) for words in reversed_words]

In [8]: rejoined_words
Out[8]: ['three two One', 'six five Four', '']

In [9]: capitalized_sentences = [sentence.capitalize() for sentence in rejoined_words]

In [10]: capitalized_sentences
Out[10]: ['Three two one', 'Six five four', '']

In [11]: '. '.join(capitalized_sentences)
Out[11]: 'Three two one. Six five four. '

注意:

速度

您可能想知道运行速度有多快...

timeit 在这里很方便。

Your example

> python -m timeit <<EOF
def reverse_sentences(str):
 newlist=str.split(".")
 newstr=''
 for s in newlist[0:-1]:
   words=s.split()
   words=words[::-1]
   words[0]=words[0][0].upper()+words[0][1:]
   words[-1]=words[-1][0].lower()+words[-1][1:]
   for e in range(len(words)):
      words[e].strip()
      if words[e] != words[-1]:
           newstr+=words[e]+" "
      else:
           newstr+=words[e]
   newstr+=". "
 return newstr

reverse_sentences("One two three. Four five six.")
EOF
100000000 loops, best of 3: 0.012 usec per loop

My example

> python -m timeit <<EOF
def reverse_sentences(text):     
    sentences = text.split('.')                                                                      
    reversed_words = (reversed(words.split()) for words in sentences)
    rejoined_words = (' '.join(words) for words in reversed_words)
    capitalized_sentences = (sentence.capitalize() for sentence in rejoined_words)
    return '. '.join(capitalized_sentences)

reverse_sentences("One two three. Four five six.")
EOF
100000000 loops, best of 3: 0.012 usec per loop

zhangxaochen's example

> python -m timeit <<EOF
t="One two three. Four five six."
' '.join(' '.join(sentence.lower().split()[::-1]).capitalize()+'.' for sentence in t.split('.')[:-1])
EOF                                                                  
100000000 loops, best of 3: 0.012 usec per loop

结论

通过遵守The Zen of Python 优化可读性和可维护性,您的代码将“更加pythonic”。

【讨论】:

  • Python 中有大写函数?!哇,谢谢!
  • @garlfd: str.capitalize(),是的!
  • 并且可能将 strip() 应用于最终结果以消除最后的额外空间?
  • @lessthanl0l:是的。可以进行很多调整。我的回答是关于方法
猜你喜欢
  • 2013-06-05
  • 2012-06-07
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
相关资源
最近更新 更多