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 。