LoginSignup
1
5

More than 3 years have passed since last update.

Python個人的メモその3:スライス編~「始め:終わり:間隔」が基本!~

Last updated at Posted at 2019-05-25

はじめに

pythonにはとっても便利な仕組みがあります。そのうちの一つがスライス
どんなものかは例を見ればすぐわかります。

リスト操作

要素数10のリストの中から(先頭を0番目として)「2番目から4番目」を取り出したいときどうします?
わざわざfor文を回しますか? pythonではそんな必要はありません。
こうすればよいのです。

slice_list
l=[10,9,8,7,6,5,4,3,2,1]
print(l[2:5])  #[8,7,6]

リスト名[始め:終わり]と指定すると,リストの一部分を取り出せるわけです.
結果からわかるように、l[2:5]と指定したとき2番目から3番目までしか取れていません。これは、このように考えると納得がいきます。
【0】10【1】9 【2】 8【3】7【4】6 【5】

間隔を指定する

また、奇数番目の要素だけ取り出したいとき、つまり1番目から一つ飛ばしで取り出したいときはこのようにします。

slice_list_odd
l=[10,9,8,7,6,5,4,3,2,1]
print(l[1:10:2])  #[9,7,5,3,1]

今度はリスト名[始め:終わり:間隔]としました.間隔は省略可能で、その場合1がデフォルトの値として扱われます。
なお、始めと終わりも同様に省略ができ、例えば[:][0:len(l)]を意味します。これはつまり元のリストと等しいですね。

負の値も指定可能

また、これらに負の値を設定することも可能です。
l[-2:]の結果はこのようになります。

list_slice_minus
l=[10,9,8,7,6,5,4,3,2,1]
print(l[-2:])  #[2,1]

「終わりから数えて2番目」から最後までが取り出されました.以下のように考えることが出来ます.

【-5】5【-4】4【-3】3 【-2】 2【-1】1

また,間隔に-1を指定すると,逆からリストを取り出せます(順序が逆転するということです).
ちなみに同様の操作はリスト名.reverse()でも可能です.

list_reverse
l=[10,9,8,7,6,5,4,3,2,1]
print(l[::-1])  #[1,2,3,4,5,6,7,8,9,10]

文字列操作

さて、この「始め:終わり:間隔」の考え方は他の場面でも使えます。

文字列は,リストと同じように扱うことが出来ます.(ただし文字列は変更不可なので注意)
どういうことかというと、文字列のある一部分を取り出したいときにも、「始め:終わり:間隔」のスライスが使えるということです。

str_slice
s='abcdefg'
print(s[2:6])  #'cdef'
#変数に入れなくても同じように扱える
print('abcdefg'[2:6])  #'cdef'

文字列に新たな文字を挿入/置換する

スライスを使うと,本来変更不可な文字列に新たに文字を挿入することが出来ます.
要は入れたい位置で文字列を二分割して,その間に文字を挿入してから再びくっつければよいのです.
少し変えると挿入ではなく任意の位置の文字を置換できます.

insert_str
#0から数えて5番目の後に挿入
def insert_str(s, c, idx):
    return s[:idx] + c + s[idx:]

#0から数えて5番目を置換
def replace_str(s, c, idx):
    return s[:idx] + c + s[idx+1:]

s='123456'
print(insert_str(s, 'A', 2))  #'123A456'
print(replace_str(s, 'A', 2))  #'12A456'

range

厳密にはスライスと呼ばれるものではないと思うのですが、「始め:終わり:間隔」の考え方は同じなので取り上げます。

for文を回す時,しばしばrangeを用います.

range_sample
s=''
for i in range(5):
    s += str(i)
print(s)  #'01234'

このrangeは コンマ区切りで 始めと終わりと間隔を指定できます.

range_sample2
s=''
for i in range(1,10,2):
    s += str(i)
print(s)  #'13579'

ただし,range(1,,2)などはエラーになるので注意が必要です.

おまけ:enumerate

rangeを取り上げたのでどうせならenumerateも紹介しておきます.
もはやスライスでも何でもないのですが.
リスト内の全要素に順番にアクセスするとき,indexも同時に取得したい時に使います.
for文を書く際,リストをenumerateで包むだけです.
第二引数に数字を指定すると,indexがどの数字で始まるかを指定できます.全要素を取得することに変わりはありません.

enumerate_sample
l=['a','b','c','d']
#index,value
for index, name in enumerate(l):
   print(index, name)
'''
0 a
1 b
2 c
3 d
'''

#第二引数は,indexをどの数字から始めるか指定する(全要素を取得すること自体は変わらない) 省略すると0
for index, name in enumerate(l,1):
   print(index, name)
'''
1 a
2 b
3 c
4 d
'''

おわりに

スライス操作は非常に強力です.ぜひマスターしましょう.

1
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5