やること
Python中級者くらいになったら試してみたいテクニックを5つ選んでみました。
テクニック1 enumerate()
配列aをfor文で処理する際、添字が不要であれば for value in a: と要素を引き出し、添字が必要であれば for i in range(len(a)): と添字を引き出すかと思いますが、enumerate() を用いると両方とも叶います。
a = ['x', 'y', 'z']
for i, value in enumerate(a):
print(i, value)
0 x
1 y
2 z
辞書aについても似たようなことができます。
a = {'x':9, 'y':8, 'z':7}
for i, (key, value) in enumerate(a.items()):
print(i, key, value)
0 a 9
1 b 8
2 c 7
テクニック2 try~except
try~except を用いるとエラーを無視してプログラムの実行を進めることができます。例えばゼロ除算を試してみます。通常であればエラーで止まってしまうところが、except の内容が実行されて継続します。
for i in range(-5, 5):
try:
print(10/i)
except:
print('err in {}'.format(i))
-2.0
-2.5
-3.3333333333333335
-5.0
-10.0
err in 0
10.0
5.0
3.3333333333333335
2.5
これが活躍する場面として、例えば「フォルダ内の画像をすべてリサイズしたいが、一部の画像ファイルは破損している。ファイル名やファイル容量で破損状態を判別できないので、読み込んでエラーが出たら処理をスルーしたい。」が考えられます。
テクニック3 for~else, while~else
if~else と同様に、for~else と while~else もあります。break とセットで用いられ、for や while が途中で break されることなく最後まで実行されると、おめでとうということで else が実行されます。
次の例では break が起きず else が実行されます。
for i in range(5):
print(i)
if i == 9:
print('強制終了')
break
else:
print('正常終了')
0
1
2
3
4
正常終了
次の例では break が起き、else が実行されません。
i = 0
while i < 5:
print(i)
if i == 3:
print('強制終了')
break
i += 1
else:
print('正常終了')
0
1
2
3
強制終了
テクニック4 多重ループの抜け方
そもそもPythonで多重ループを使うとPython警察に怒られるわけですが、5分で書く必要があるときはそんなことも言っていられません。例えば、3重for文を抜けるには終了フラグを使うことが多いのではないでしょうか。
end = False
for i in range(3):
for j in range(3):
for k in range(3):
print(i, j, k)
if i+j+k > 2:
end = True
print('強制終了')
break
if end:
break
if end:
break
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
強制終了
しかし、後ろに break がダラダラと続くのは美しくありませんし、10重for文ともなると尾ひれが長くなってしまいます。そこで3つの方法を紹介します。出力はいずれも上と同じです。
方法1:関数化して return で抜ける
def function():
for i in range(3):
for j in range(3):
for k in range(3):
print(i, j, k)
if i+j+k > 2:
print('強制終了')
return
function()
方法2:try~except でエラーを起こして抜ける
try:
for i in range(3):
for j in range(3):
for k in range(3):
print(i, j, k)
if i+j+k > 2:
raise Exception
except Exception:
print('強制終了')
方法3:itertools.product() で多重for文を避ける
import itertools
for i, j, k in itertools.product(range(3), range(3), range(3)):
print(i, j, k)
if i+j+k > 2:
print('強制終了')
break
テクニック5 *args, **kwargs
予習として、アスタリスクを使うと空気を読んで複数の要素を配列として格納してくれます。
a, *b = [1, 2, 3, 4]
print(a, b)
a, *b = [1, 2, [3, 4]]
print(a, b)
a, *b, c = [1, 2, 3, 4]
print(a, b, c)
1 [2, 3, 4]
1 [2, [3, 4]]
1 [2, 3] 4
*args
これを利用して、関数において任意個数の引数をタプル型で格納することができます。
def function(a, *b):
print(a, b)
function(1)
function(1, [2, 3], 4)
1 ()
1 ([2, 3], 4)
なお、*args とデフォルト値を持つ引数を一緒に使う場合は非常に複雑なルールがあります。興味がある方は沼に足を踏み入れてみてください。
**kwargs
**kwargs は任意個数のキーワード引数を辞書型で格納することができます。
def function(a, **b):
print(a, b)
function(1)
function(1, x=2, y=3)
1 {}
1 {'x': 2, 'y': 3}
まとめ
日々勉強です。