この記事では、Pythonのスライスの使い方を解説します。
リストなどのシーケンス型のオブジェクトを使っていると部分的な要素にアクセスしたい場面が多々あります。そんな時は、スライスを使うことで必要な要素のみにアクセスできます。
スライスは、リスト含むシーケンスオブジェクトの要素をインデックスを用いて部分的に選択することができます。選択した要素は、取得・変更・削除を行うことができます。
それでは、スライスの使い方を見ていきましょう!
スライスの基本
スライスを使うことでシーケンスの要素を部分的に選択できる。スライスは以下のようにシーケンスの後ろの角括弧([]
)内にstart
、stop
、step
をコロン(:
)で区切って指定します。
シーケンス[start:stop:step]
- start、stop、stepには、インデックスを指定する
- start、stop、stepは、全て省略可能
- 範囲外のインデックスを指定してもエラーにならない
- シーケンス: 複数の要素を順序付けして保存できるコレクションのこと(リスト、タプル、文字列など)
スライスはシーケンスの先頭や末尾の要素を削って処理したい時に使われることが多い。
l = ['必要ない', '必要', '必要', '必要ない']
for e in l[1:-1]:
print(e)
# 必要
# 必要
それでは、スライスのstart
、stop
、step
の指定方法を見ていきます。
startからstopまで: [start:stop]
スライスのstart
とstop
を指定することでstart <= N < stop
の要素を取得できます。
シーケンス[start:stop]
2 <= N < 4
の範囲の要素を取得してみます。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[2:4]) # [3, 4]
start > stop
だと値は取得できません。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[4:2]) # []
先頭からstopまで: [:stop]
スライスのstop
のみを指定することで0 <= N < stop
の要素を取得できます。
シーケンス[:stop] # コロンを忘れないように注意
これは以下のコードと等価です。
シーケンス[0:stop]
0 <= N < 4
の要素を取得してみます。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[:4]) # [1, 2, 3, 4]
コロンを忘れると通常のインデックス呼び出しになってしまうので注意。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[4]) # 5
startから末尾まで: [start:]
スライスのstart
のみ指定することでstart
から末尾までの要素を取得できます。
シーケンス[start:] # コロンを忘れないように注意
これは以下のコードと等価です。
シーケンス[start:len(シーケンス)]
2 <= N < len(vals)
の範囲の要素を取得してみます。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[2:]) # [3, 4, 5, 6, 7]
stepの指定: [::step]
スライスのstep
を指定するとその数値ごとに要素が取得されます。step
を省略した場合はstep = 1
となっています。
シーケンス[start:stop:step]
start
とstop
を省略してステップ数のみを指定することもできます。
シーケンス[::step] # コロンを忘れないように注意
異なるstep
を指定して取得される要素がどのようになるか見てみましょう!
l = [1, 2, 3, 4, 5, 6, 7]
print(l[::2]) # [1, 3, 5, 7]
print(l[::3]) # [1, 4, 7]
print(l[::4]) # [1, 5]
print(l[::5]) # [1, 6]
print(l[::6]) # [1, 7]
print(l[::7]) # [1]
step
を指定することで任意の間隔で要素を取得することができます。アクセスしたい要素が一定間隔で配置されている場合に使用します。
全て省略: [:]、[::]
スライスのstart
、stop
、step
は省略可能です。なので以下のような書き方が可能です。
シーケンス[:]
シーケンス[::]
これらの書き方は全ての要素を取得します。
s = [1, 2, 3]
print(s[:]) # [1, 2, 3]
print(s[::]) # [1, 2, 3]
負の整数を指定する
スライスのstart
、stop
、step
に負の整数を指定することで末尾から要素を指定することができます。それぞれの挙動を見てみましょう。
l = [1, 2, 3, 4, 5, 6, 7]
# startに負の整数を指定する
print(l[-1:]) # [7]
print(l[-2:]) # [6, 7]
print(l[-3:]) # [5, 6, 7]
print(l[-4:]) # [4, 5, 6, 7]
# stopに負の整数を指定する
print(l[:-1]) # [1, 2, 3, 4, 5, 6]
print(l[:-2]) # [1, 2, 3, 4, 5]
print(l[:-3]) # [1, 2, 3, 4]
print(l[:-4]) # [1, 2, 3]
# startとstopに負の整数を指定する
print(l[-2:-1]) # [6]
print(l[-3:-1]) # [5, 6]
print(l[-4:-1]) # [4, 5, 6]
step
に負の整数を指定することで逆順で要素を取得できます。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[::-1]) # [7, 6, 5, 4, 3, 2, 1]
print(l[::-2]) # [7, 5, 3, 1]
print(l[::-3]) # [7, 4, 1]
step
に負の整数を指定した場合にstart
とstop
を指定するには以下のようになる。
l = [1, 2, 3, 4, 5, 6, 7]
print(l[-1:-8:-1]) # [7, 6, 5, 4, 3, 2, 1]
print(l[-1:-7:-1]) # [7, 6, 5, 4, 3, 2]
print(l[6::-1]) # [7, 6, 5, 4, 3, 2, 1]
print(l[5:2:-1]) # [6, 5, 4]
これは直感的ではないので少し分かりづらいですね。あまりに手の込んだ指定方法は極力使わない方が良いかもしれませんね。
スライスオブジェクト
slice()
でスライスオブジェクトを生成することができます。[]
内にスライスオブジェクトを指定することで、その範囲で要素を選択できます。
slice(stop)
slice(start, stop[, step])
スライスオブジェクトを用いて範囲を指定して見ましょう!
l = [1, 2, 3, 4]
# スライスオブジェクト生成
so = slice(1, 3)
print(l[so]) # [2, 3]
スライスで選択した範囲の操作
スライスで選択した範囲は、取得するだけでなく代入や削除を行うことが可能です。
代入
スライスで選択した範囲にイテラブルオブジェクトを代入することができます。この時、選択した範囲と代入するイテラブルオブジェクトの要素数が異なっていても代入可能です。
l = [1, 2, 3, 4, 5]
l[1:4] = [10, 11]
print(l) # [1, 10, 11, 5]
イテラブルオブジェクト以外のオブジェクト(スカラー値)を代入するとエラーが発生します。
l = [1, 2, 3, 4, 5]
l[1:4] = 10
実行結果
Traceback (most recent call last):
File "/Users/user/Desktop/Python/main.py", line 3, in
l[1:4] = 10
~^^^^^
TypeError: can only assign an iterable
範囲外を指定することで新たに要素を挿入することもできます。
l = [1, 2, 3, 4, 5]
l[len(l):10] = [10, 11, 12]
print(l) # [1, 2, 3, 4, 5, 10, 11, 12]
ただし、step
を指定した場合は、選択した範囲と代入するイテラブルオブジェクトの要素数が同じじゃないとエラーとなってしまうので注意してください。
l = [1, 2, 3, 4, 5]
l[1:4:2] = [10, 11]
print(l) # [1, 10, 3, 11, 5]
l[1:4:3] = [10, 11] # ValueError: attempt to assign sequence of size 2 to extended slice of size 1
削除
del
文を使うことで選択した範囲の要素を削除することが可能です。
l = [1, 2, 3, 4, 5]
del l[1:4]
print(l) # [1, 5]
余談: スライスは浅いコピー
スライスで取得した値は浅いコピーで生成されたものである。つまりは、スライスで取得した値の中にネストされたリストや辞書があると元のオブジェクトに影響を及ぼしてしまう。
# ネストされたリストを含んだリスト
o = [[1, 2, 3], 4, 5]
# ネストされたリストを取得
s = o[:2]
print(s) # [[1, 2, 3], 4]
# 変更を加える
s[0][0] = 10
print(s) # [[10, 2, 3], 4]
# 元のオブジェクトも変わっている
print(o) # [[10, 2, 3], 4, 5]
まとめ
この記事では、Pythonのスライスについて解説しました。
スライスを使うことでシーケンス型の要素に範囲的にアクセスすることができました。
実際にスライスを使用する場合、先頭、または末尾の要素以外を取得したいことが大体です。なので、以下のような方法さえ覚えておけば問題ありません。
l = ['必要ない', '必要', '必要', '必要ない']
print(l[1:-1]) # ['必要', '必要']
今回の内容はここまでです。それではまたどこかで〜( ・∀・)ノ