python

pythonの便利ショートカット10選【後編】

前回の記事では前編として5つ紹介しました。

今回は続編として、残りの5個を紹介します

前回記事

ternary conditions

日本語でいうところの三項演算子です。注意としては、通常のif文ではelseを取らなくても問題はありませんが、三項演算子では必須です。

x = 1 if 2 > 3 else 0 

javascriptだと少し書き方が違うので、pythonもjavascriptも使う人は混ざらないように気をつけましょう。

x = 2 > 3 ? 1 : 0

三項演算子を使わないのであれば、コードが長くなります。使い所としては、短いコードを一行で書きたい時に重宝します。長いコードも書けはしますが、可読性落ちるので単純なコードのみに使うようにしてください。

if 2 > 3:
    x = 1
else:
    x = 0

zip function

データ処理でよく使う機能です。データ分析のためのデータがリストで提供されているとします。人に関する情報で、名前・性別・生年月日などが情報として持っていますが、全て別の変数で管理されていると上手く処理ができません。

そこで必要な情報を一括りにして分析しやすくしたりします。その方法を見ていきます。

names  = ['tom', 'sum', 'jon', 'billy']
ages  = [21, 19, 18, 43]
births = ['2000/4/18', '1998/7/9', '2001/10/29', '2006/12/5']

print(list(zip(names, ages, births)))
> [('tom', 21, '2000/4/18'), ('sum', 19, '1998/7/9'), ('jon', 18, '2001/10/29'), ('billy', 43, '2006/12/5')]

要素数があっていない場合には、エラーにはならず一番少ない数の要素に合わせられ残りはなかったものとして扱われます。

names  = ['tom', 'sum', 'jon', 'billy']
ages  = [21, 19, 18, 43, 56]
births = ['2000/4/18', '1998/7/9', '2001/10/29', '2006/12/5']

print(list(zip(names, ages, births)))
> [('tom', 21, '2000/4/18'), ('sum', 19, '1998/7/9'), ('jon', 18, '2001/10/29'), ('billy', 43, '2006/12/5')]

agesの変数に要素を足しましたが、出力は同様の結果です。

分かりやすい使い方を見せましたが、上記のような使い方はあまりせずに、for文との組み合わせでよく使います。

例えば、ageが20歳以上の人のみを出力といった形です。

names = ['tom', 'sum', 'jon', 'billy']
ages = [21, 19, 18, 43]
births = ['2000/4/18', '1998/7/9', '2001/10/29', '2006/12/5']

for name, age, birth in zip(names, ages, births):
    if age > 20:
        print(name, birth)

*args and **kwargs

argsはargumentの略で引数のことです。

関数を定義した時に見ますが、引数の個数が一定でない場合があります。そういった時に*argsのような形をとります。

まずは基本的な引数の取り方と実行の仕方を見てみます。

def func1(arg1, arg2, arg3):
    print(arg1, arg2, arg3)

def func2(arg1=None, arg2=None, arg3=None):
    print(arg1, arg2, arg3)

func1(1, 2, 3)
func2(arg2=1, arg1=2)

func1は3つの引数を取り、初期値を設定していないので3つの値を取らないとエラーになります。

func2はfunc1と同様に3つの引数をとりますが、初期値を設定しているので全ての引数の値を設定する必要はありません。

args = [0, 1, 2]
kwargs = {'arg2': 2, 'arg1': 1, 'arg3': 3}

func1(*args)
func2(*kwargs)

func2(**kwargs)
# **kwargsと同義
# func2(arg2=2, arg1=1, arg3=3)

*argsを使えば、unpackingと同じ要領で分解し展開することができます。

*kwargsの方はキーの部分が展開され引数に渡されます。

ただし、func2(**kwargs)のようにアスタリスクを二つ重ねるとキーを引数の名前に設定し、それに対応した値を格納します。

一番よく見るところでは、関数の引数に使われるので見ておきます。

def func3(*args, **kwargs):
    print(args)
    print(kwargs)

func3(1, 2, a=3, b=4)

これから分かることは、キーを指定しないものはargsにタプルとして入り、キーを指定したものはkwargsに辞書として入ります。

for elseとwhile else

else文は良くif文と使うので見ますが、forとwhile使うことができます。

例として、1~9までの配列があって特定の数値を見つける処理を考えてみます。

まずはfor elseを使わない例です。

search = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
target = 7
found = False
for e in search:
    if e == target:
        print('Hit')
        found = True
        break

if not found:
    print('not found')

7という数字があるか探し当てるプログラムです。targetを10に変えても見つからない場合も試してみて正しく動作するか確かめてください。

これを書き換えるとこのようになります。

search = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
target = 7
for e in search:
    if e == target:
        print('Hit')
        break
else:
    print('not found')

該当したかどうかのフラグが必要無くなったのが分かると思います。

whileを使う場合には少し違った書き方になりますが、これはforとwhileの違いなので参考程度に

search = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
target = 7

i = 0
while i < len(search):
    e = search[i]
    if e == target:
        print('Hit')
        break
    i += 1
else:
    print('not found')

sort by key

数字の羅列が格納されたリストが与えられていて、昇順もしくは降順にソートしたい時があります。

単純な場合にはsortメソッドだけ使ってあげればいいのですが、それでは上手くいかない時に使えたりします。

例を見てみます。

lst = [[4, 2], [3, 1], [6, 3], [7, -1], [5, 4], [8, 6]]

lst.sort()
print(lst)
> [[3, 1], [4, 2], [5, 4], [6, 3], [7, -1], [8, 6]]

ネストされたリストをデフォルトのままソートしようとすると、最初の要素を比較してソートします。

実は、2番目の要素を用いてソートしたい時があった場合や、1番目と2番目の要素と足した値でソートしたいといった時にはデフォルトのままだと対応できません。

lst = [[4, 2], [3, 1], [6, 3], [7, -1], [5, 4], [8, 6]]

lst.sort(key=lambda x: x)
print(lst)
# 1番目と2番目の要素と足した値でソート
lst.sort(key=lambda x: x + x[0])
print(lst)

3行目と6行目が上手く表示できていないのでこちらで補足します。

3行目:lst.sort(key=lambda x: x[1])

6行目:lst.sort(key=lambda x: x[1] + x[0])

keyという引数を用いると、複雑な状況でも簡単にソート対応できるようになります。

lambdaは一行で関数が書けるメソッドですが、以下と同義です。

lst = [[4, 2], [3, 1], [6, 3], [7, -1], [5, 4], [8, 6]]

def sort_func(x):
    return x[0] + x

lst.sort(key=sort_func)
print(lst)

4行目が上手く表示できていないのでこちらで補足します。

4行目:return x[0] + x[1]

これの欠点としては、元の変数を変更してしまうので、色々と不都合が出てきてしまうこともあります。

そこで、元の変数を変えずにソートした結果を別の変数へと格納したりする方法もあります。

lst = [[4, 2], [3, 1], [6, 3], [7, -1], [5, 4], [8, 6]]

def sort_func(x):
    return x[0] + x

print(sorted(lst, key=sort_func))

以上、pythonの便利なショートカット10選を紹介してきました。

これを機に色々と便利な機能を使えるようになってみてはいかがでしょうか。