23
Effective Python 読読読 #1 読読 @Wizard_of_Oz__

Effective python #5, #6

Embed Size (px)

Citation preview

Page 1: Effective python #5, #6

Effective Python読書会 #1

オズ @Wizard_of_Oz__

Page 2: Effective python #5, #6

自己紹介• オズ @Wizard_of_Oz__• 拝承系エンジニア

• Python 歴一ヶ月なんでイジメないでください (>_<)

Page 3: Effective python #5, #6

EffectivePython

項目 5シーケンスをどのようにスライスするか知っておく

Page 4: Effective python #5, #6

シーケンスをスライスする構文• シーケンスのスライス

– シーケンスの部分に簡単にアクセス

– 組み込みでは list, str, bytes で利用可

>>> S = [‘h’, ‘o’, ‘g’, ’e’, ’f’, ’u’, ’g’, ’a’]>>> print(s[2:6])[‘g’, ’e’, ’f’, ’u’]• 構文

somelist[start:end]

Page 5: Effective python #5, #6

シーケンスをスライスする構文somelist[start:end]

s[2:6]

0

h

1

o

2

g

3

e

4

f

5

u

6

g

7

a

含む 含まない

Page 6: Effective python #5, #6

シーケンスをスライスする構文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)余分な添字は省く

Page 7: Effective python #5, #6

シーケンスをスライスする構文・要素にはマイナスも指定可能

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

Page 8: Effective python #5, #6

シーケンスをスライスする構文・ -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

Page 9: Effective python #5, #6

シーケンスをスライスする構文a[:] a[:5] a[:-1] a[4:] a[-3:] a[2:5] a[2:-1] a[-3:-1]

Page 10: Effective python #5, #6

シーケンスをスライスする構文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]

Page 11: Effective python #5, #6

範囲を超えた添字• リストの境界を超えた添字も適切に扱われる

input = a[:20]

• 直接アクセスは例外

a[20]>>>IndexError: list index out of range

Page 12: Effective python #5, #6

スライスはコピペ( 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’]

Page 13: Effective python #5, #6

代入によって適切に伸び縮み• 代入するスライスの長さは同じでなくて良い

>>> 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’]

Page 14: Effective python #5, #6

代入によって適切に伸び縮み>>> 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)

Page 15: Effective python #5, #6

まとめ• 冗長を避ける “ [0:” や” len()]” を使用しない

• 境界外の添字が許される a[:20] #a = [1, 2, 3]• 代入は長さが違っても合わせてくれる #a[1:10] = [1, 2]

Page 16: Effective python #5, #6

EffectivePython

項目 61 つのスライスでは、 start, end, stride を使わない

Page 17: Effective python #5, #6

スライスの増分を設定できる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

増分

Page 18: Effective python #5, #6

スライスの増分を設定できる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

Page 19: Effective python #5, #6

stride を使ったよくある技法>>> a = ‘abcdefgh’>>> a[::-1]‘hgfedcba’

☆Unicode 文字列にはうまく動かない

>>> s = ‘ ほげ’ .encode(‘utf-8’)>>> x = s[::-1]>>> x.decode(‘utf-8’)

Page 20: Effective python #5, #6

使用例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]

Page 21: Effective python #5, #6

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’]

Page 22: Effective python #5, #6

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’]

Page 23: Effective python #5, #6

まとめ• start, end, stride を指定すると分かりにくいことがある

• stride はできるだけ正の値

• stride は start, end どちらか一方のみと一緒に使う

• どうしてもすべて必要な時は 2 行に分ける– もしくは itertools の islice メソッドを使う (start, end, stride に負の値を許

さない )– ( 項目 46 :組み込みアルゴリズムとデータ構造を使う 参照 )