Recipe 1.7. Reversing a String by Words or Characters
Recipe 1.7. 以单词或字符为单位对字符串进行反序排列
Credit: Alex Martelli
问题
您想将字符串中的字符或单词进行反序。
解法
字符串是不可变(immutable)对象,因此若要进行反序排列操作,我们就需要生成新字符串。最简单的反序办法是以 -1 为步进单位进行切割操作,使切割操作以反序进行:
revchars = astring[::-1]
要以单词为单位进行反序,我们须要做一个单词的列表,然后将其反序,再将其重新连接成字符串并以空格隔开:
revwords = astring.split( ) # 字符产 -> 单词的列表
revwords.reverse( ) # 将列表元素反序
revwords = ' '.join(revwords) # 单词列表 -> 字符串
若您喜欢简约紧凑的单行语句,也可以这样写:
revwords = ' '.join(astring.split( )[::-1])
若您须要以单词为单位进行反序,且同时又希望保留单词之间的空格不动,则可以用正则表达式来进行分割:
import re
revwords = re.split(r'(/s+)', astring) # 用'(...)'来指明要包含分隔符
revwords.reverse( ) # 原地进行反序
revwords = ''.join(revwords) # 字符串列表 -> 字符串
须要注意的是,这里必须使用空字符串来进行连接操作,因为单词之间的空格被保留在
revwords 列表中(通过在
re.split 中使用正则表达式,其中包含了用括号括起来的组)。若您愿意,同样也可以将其写成单行语句:
revwords = ''.join(re.split(r'(/s+)', astring)[::-1])
但这样写就显得太过紧凑,不易阅读,不算是好的 Python 代码了!
讨论
在 Python 2.4 中,您可以使用新的内建函数
reversed 撰写更易读的单行语句,来完成以单词为单位的反序操作,不必使用上述不太易读的扩展切割指示符
[::-1]:
revwords = ' '.join(reversed(astring.split( )))
revwords = ''.join(reversed(re.split(r'(/s+)', astring)))
以字符为单位进行反序,在 Python 2.4 中
astring[::-1] 仍然是最佳方案,原因是为了使用
reversed,就不得不额外使用一个
''.join 调用:
revchars = ''.join(reversed(astring))
新的
reversed 内建函数不是返回结果字符串,而是返回一个 iterator,适用于循环或传递给某些“accumulator(累积器)”可调用体(比如
''.join)。
请参见
Library Reference 和 Python in a Nutshell 关于 sequence types 和 slicing 的文档,以及 Python 2.4 中新加入的
reversed 内建函数;Perl Cookbook recipe 1.6 。