Upload
bontakun
View
224
Download
2
Embed Size (px)
Citation preview
Effective Python読書会 #1
オズ @Wizard_of_Oz__
自己紹介• オズ @Wizard_of_Oz__• 拝承系エンジニア
• Python 歴一ヶ月なんでイジメないでください (>_<)
EffectivePython
項目 5シーケンスをどのようにスライスするか知っておく
シーケンスをスライスする構文• シーケンスのスライス
– シーケンスの部分に簡単にアクセス
– 組み込みでは list, str, bytes で利用可
>>> S = [‘h’, ‘o’, ‘g’, ’e’, ’f’, ’u’, ’g’, ’a’]>>> print(s[2:6])[‘g’, ’e’, ’f’, ’u’]• 構文
somelist[start:end]
シーケンスをスライスする構文somelist[start:end]
s[2:6]
0
h
1
o
2
g
3
e
4
f
5
u
6
g
7
a
含む 含まない
シーケンスをスライスする構文somelist[ : ]
s[:4] #[‘h’, ‘o’, ‘g’, ’e’]
0
h
1
o
2
g
3
e
4
f
5
u
6
g
7
a
0 len(s)余分な添字は省く
シーケンスをスライスする構文・要素にはマイナスも指定可能
s[3:-3] #[’e’, ’f’]
-8
0
h
-7
1
o
-6
2
g
-5
3
e
-4
4
f
-3
5
u
-2
6
g
-1
7
a
シーケンスをスライスする構文・ -n を使うとき、 n=0 がくると予想外の結果に
s[-n:] # s[:]
-8
0
h
-7
1
o
-6
2
g
-5
3
e
-4
4
f
-3
5
u
-2
6
g
-1
7
a
シーケンスをスライスする構文a[:] a[:5] a[:-1] a[4:] a[-3:] a[2:5] a[2:-1] a[-3:-1]
シーケンスをスライスする構文a[:] #[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]a[:5] #[‘a’, ‘b’, ‘c’, ’d’, ’e’]a[:-1] #[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’]a[4:] # [’e’, ’f’, ’g’, ’h’]a[-3:] # [’f’, ’g’, ’h’]a[2:5] # [‘c’, ’d’, ’e’]a[2:-1] # [‘c’, ’d’, ’e’, ’f’, ’g’]a[-3:-1] # [’f’, ’g’]
a[:] a[:5] a[:-1] a[4:] a[-3:] a[2:5] a[2:-1] a[-3:-1]
範囲を超えた添字• リストの境界を超えた添字も適切に扱われる
input = a[:20]
• 直接アクセスは例外
a[20]>>>IndexError: list index out of range
スライスはコピペ( not カット&ペースト )>>> a = [‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]>>> b = a[:4] # [‘a’, ‘b’, ‘c’, ’d’]>>> b[1] = 99>>> print(b)[‘a’, 99, ‘c’, ’d’]>>> print(a)[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]
代入によって適切に伸び縮み• 代入するスライスの長さは同じでなくて良い
>>> b = a[:]>>> b[1:-1] = [1, 2, 3]>>> print(a)[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]>>> print(b)[‘a’, 1, 2, 3, ’h’]
代入によって適切に伸び縮み>>> b = a>>> print(a)[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]>>> a[:] = [1, 2, 3]>>> print(a)[1, 2, 3]>>> assert a is b>>> (no assertion)
まとめ• 冗長を避ける “ [0:” や” len()]” を使用しない
• 境界外の添字が許される a[:20] #a = [1, 2, 3]• 代入は長さが違っても合わせてくれる #a[1:10] = [1, 2]
EffectivePython
項目 61 つのスライスでは、 start, end, stride を使わない
スライスの増分を設定できるsomelist[start:end:stride]
a[::2] #[‘a’, ‘c’, ’e’, ’g’]
0
a
1
b
2
c
3
d
4
e
5
f
6
g
7
h
増分
スライスの増分を設定できるa[::2] #[‘a’, ‘c’, ’e’, ’g’]
a[1::2] #[‘b’, ‘d’, ’f’, ’h’]
0
a
1
b
2
c
3
d
4
e
5
f
6
g
7
h
a b c d e f g h
stride を使ったよくある技法>>> a = ‘abcdefgh’>>> a[::-1]‘hgfedcba’
☆Unicode 文字列にはうまく動かない
>>> s = ‘ ほげ’ .encode(‘utf-8’)>>> x = s[::-1]>>> x.decode(‘utf-8’)
使用例a = [‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]a[::2]a[::-2]a[2::2]a[-2::-2]a[-2:2:-2]a[2:2:-2]
1 つのスライスでstart, end, stride を使わない• start, end と一緒に stride を使わない
• stride はできるだけ正の値に
• どうしても組み合わせる必要があるときはstride のみとスライスのみに分けて使う
>>> a #[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]>>> a[2:-2:2] #[‘c’, ’e’]>>> b = a[::2] #[‘a’, ‘c’, ’e’, ’g’]>>> c = b[1:-1] #[‘c’, ’e’]
1 つのスライスでstart, end, stride を使わない• どうしても組み合わせる必要があるときは
stride のみとスライスのみに分けて使う
>>> a #[‘a’, ‘b’, ‘c’, ’d’, ’e’, ’f’, ’g’, ’h’]>>> a[2:-2:2] #[‘c’, ’e’]>>> b = a[::2] #[‘a’, ‘c’, ’e’, ’g’]>>> c = b[1:-1] #[‘c’, ’e’]>>> b = a[2:-2] #[‘c’, ‘d’, ’e’, ’f’]>>> c = b[::2] #[‘c’, ’e’]
まとめ• start, end, stride を指定すると分かりにくいことがある
• stride はできるだけ正の値
• stride は start, end どちらか一方のみと一緒に使う
• どうしてもすべて必要な時は 2 行に分ける– もしくは itertools の islice メソッドを使う (start, end, stride に負の値を許
さない )– ( 項目 46 :組み込みアルゴリズムとデータ構造を使う 参照 )