ni_haruのブログ

ほぼ日記

Pythonで言語処理100本ノックを解く 00. 文字列の逆順

Python言語処理100本ノックを解いてみます。

環境

Ubuntu 16.04.3 LTS
Python 3.5.2

00.文字列の逆順

文字列"stressed"の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.

解答

# -*- coding: utf-8 -*-

def reverse(s):
    return s[::-1]

if __name__ == "__main__":
    print(reverse("stressed"))

自分で最初解いたときは、"".join(reverse(s)) と書いていましたが、スライスを使うと簡潔に書ける上に高速なので、そちらを採用しました。

スライスって?

シーケンス型(文字列はテキストシーケンス型です)に対して、s[i:j:k] と書くことで、s の「 i から j まででステップが k」の要素を取得できます。
また、k に負の数を指定すると、逆順に要素を取得できます。

s = "abcde"
s[0:4:1] # abcd
s[0:len(s):2] # ace
s[len(s):0:-1] # edcb

さらに、i, j, k は全て省略可能です。i または j を省略すると、それぞれ"端"の値を使用し、k を省略すると 1 が使用されます。 よって、以下のコードは同じ意味になります。

s[0:len(s):1] # abcde
s[::] # abcde 省略しているけど↑と同じ

逆順にする

さて、この場合 "端"の値とは 0 と len(s) のことですが、わざわざ"端"と書いたのには理由があります。
実は、どちらの端になるかは k の符号によって変わるのです。
k が負の数の場合、i が len(s) となり、j が 0 となります…と言いたいのですが、それだと上手くいきません。

s[len(s):0:-1] # edcb

終端に0を指定すると、0番目の要素の手前までを取得するので、先頭の要素が欠けますね。
と言って終端に -1 を指定すると、空になってしまいます。負の数を指定した場合、右から数えるため、要素が取得できなくなるためです。

s[len(s):-1:-1] # 空になる

これは、負の数をさらに大きくしていくと解決します。シーケンスの長さより、さらに1引いた数を終端にすれば上手くいきます。 i と j を省略しても、ちゃんと逆順の"端"(おそらく len(s) と -len(s)-1 )が使用されるので、逆順の文字列が取得できます。

s[lens(s):-len(s)-1:-1] # edcba
s[::-1] # edcba 省略しているけど↑と同じ

結論

s[::-1]と書けばよい。