"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

Pythonのシーケンススライス構文のよく使う部分をまとめておく

Pythonのスライス構文についてポイントを整理しとこうと思います。

f:id:arakan_no_boku:20181124131221j:plain

 

基本構文の確認

 

Pythonのスライス構文の基本形です。

anylist[start:end:stride]

これで。

start を省略すると「0」(つまり添え字の先頭)

end を省略すると「最後の要素まで」

stride を省略すると「1」

を意味します。

なので。

anylist[:]

は、先頭から最後までなので、元のリストの要素すべてを返すというわけです。

 

startとendでの添え字の扱いの違い

 

startに数字を指定すると、その数字が添え字になる値を含みます。

endに数字を指定すると、「指定した数字」が添え字になる値を含みません。

実際にこんな例でやってみると。

a = ['1a','2a','3a','4a','5a','6a','7a','8a','9a']

print('a[4:]',a[4:])
print('a[:4]',a[:4])

この実行結果はこうです。 

a[4:] ['5a', '6a', '7a', '8a', '9a']
a[:4] ['1a', '2a', '3a', '4a']

a[4:]のスライスだと、 a[4] が「'5a'」ですから、そこから最後まで切り取ってます。

a[:4]のスライスだと、a[0]の「'1a'」から、a[3]の「'4a'」まで切り取ってます。

 

マイナスが付くと最後尾からのカウントになる

 

マイナスの数字を指定すると、最後尾からのカウントになります。

例えば「-1」は、リストの最後の値を示します。

例えば、こんなソース。

a = ['1a','2a','3a','4a','5a','6a','7a','8a','9a']

print('a[-1:]',a[-1:])
print('a[:-1]',a[:-1])
print('a[-4:]',a[-4:])
print('a[:-4]',a[:-4])

実行した結果はこうです。

 a[-1:] ['9a']
a[:-1] ['1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a']
a[-4:] ['6a', '7a', '8a', '9a']
a[:-4] ['1a', '2a', '3a', '4a', '5a']

startが「-1」なら、最後の要素から開始なので、最後の「9a」だけを取得します。

startが「-4」なら、最後尾から4つ目である「6a」から最後までを取得します。

endが「-1」なら、0から最後尾から2つ目の「8a」までを取得します。

endが「-4」なら、先頭から、最後尾から5つ目の「5a」までを取得します。

startは「指定された位置の値を含む」のですが、endは「指定された位置を含まず、ひとつ前の値までを含む」という違いには、気をつけないといけないです。

 

文字列にスライスを適用した例

 

これらは、文字列に使っても同じことができます。

d = '一二三四五六七八九'

print('d[4:]',d[4:])
print('d[:4]',d[:4])
print('d[-1:]',d[-1:])
print('d[:-1]',d[:-1])
print('d[-4:]',d[-4:])
print('d[:-4]',d[:-4])

結果はこうなります。

d[4:] 五六七八九
d[:4] 一二三四
d[-1:] 九
d[:-1] 一二三四五六七八
d[-4:] 六七八九
d[:-4] 一二三四五 

 

スライスを文字列の文字数制限に使う

 

スライスは文字列の文字数制限とかにも使えます。

例えば、5文字までに制限したい場合、d[:5]のように最大長を指定しておけば、対象の文字列が5文字より短ければそのまま返しますし、長ければ5文字までに切り取って返すということができます。

d = '一二三四五六七八九'
ds = '一二三'

maxlen = 5
print('ds[:maxlen]',ds[:maxlen])
print('d[:maxlen]',d[:maxlen])

これはかなり便利です。

ds[:maxlen] 一二三
d[:maxlen] 一二三四五

 

strideを使って逆順にしたりとか、いろいろできます

 

3番目のパラメータ「stride」は無指定なら「1」ですが、当然別の数字を指定することもできます。

 

strideにマイナス数値を指定する

 

有名なのは、「-1」を指定して逆順にすること。

b = ['1あ','2い','3う','4え','5お','6か','7き','8く','9け']

print('b[::-1]',b[::-1])
print('reversed(b)',list(reversed(b)))

dm = '一二三四五六七八九'
print('dm[::-1]',dm[::-1])
print('reversed(dm)',''.join(list(reversed(dm))))

上記のように「reversed」を使ってもできますが、若干、ごちゃごちゃします。 

b[::-1] ['9け', '8く', '7き', '6か', '5お', '4え', '3う', '2い', '1あ']
reversed(b) ['9け', '8く', '7き', '6か', '5お', '4え', '3う', '2い', '1あ']


dm[::-1] 九八七六五四三二一
reversed(dm) 九八七六五四三二一

 

stride=2で奇数ケタ・偶数ケタの振り分け

 

あとは「stride」を2にして、奇数ケタと偶数ケタに振り分けるとか。

b = ['1あ','2い','3う','4え','5お','6か','7き','8く','9け']

print('b[::2]',b[::2])
print('b[1::2]',b[1::2])

dm = '一二三四五六七八九'
print('dm[::2]',dm[::2])
print('dm[1::2]',dm[1::2])

この結果はこんな感じ。 

b[::2] ['1あ', '3う', '5お', '7き', '9け']
b[1::2] ['2い', '4え', '6か', '8く']

 

dm[::2] 一三五七九
dm[1::2] 二四六八

うん。

とりあえず、このくらいのバリエーションを押さえておけば、忘れた時に見直して思い出せるかな・・ということで。