Python > lambda expression > defで定義した方が良い例


動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1

PyMieScattというコードでlambda expressionが使われている。
https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py#L446

lambda expressionは本来、一行であらわせる実装を匿名関数として実装する方法だと認識している。
その「一行」が長いためにコードの可読性が悪くなる。

lambda expression実装と関数での実装と比べてみる。

lambdaEquation_180401.py
import numpy as np

# on Python 3.5.2


# function
def get_ithPart(gammai, dp, dpgi, sigmagi):
    exponent = -(np.log(dp) - np.log(dpgi))**2 / (2 * np.log(sigmagi)**2)
    res = gammai * np.exp(exponent)
    res = res / (np.sqrt(2*np.pi) * np.log(sigmagi) * dp)
    return res

# lambda expression (PyMieScatt > Mie_Lognormal())
ithPart = lambda gammai, dp, dpgi, sigmagi: (gammai/(np.sqrt(2*np.pi)*np.log(sigmagi)*dp))*np.exp(-(np.log(dp)-np.log(dpgi))**2/(2*np.log(sigmagi)**2))


gammai = 2.0
dp = np.linspace(0.1, 1.0, 20)
dpgi = np.mean(dp)
sigmagi = np.std(dp)
print(dp)
print(dpgi)
print(sigmagi)

print('---')
res1 = ithPart(gammai, dp, dpgi, sigmagi)
print(res1)
res2 = get_ithPart(gammai, dp, dpgi, sigmagi)
print(res2)

$ python3 lambdaExpression_180401.py 
[0.1        0.14736842 0.19473684 0.24210526 0.28947368 0.33684211
 0.38421053 0.43157895 0.47894737 0.52631579 0.57368421 0.62105263
 0.66842105 0.71578947 0.76315789 0.81052632 0.85789474 0.90526316
 0.95263158 1.        ]
0.55
0.2731396404000978
---
[-2.59445803 -2.49295058 -2.29247964 -2.07935553 -1.87938603 -1.69949734
 -1.54021309 -1.39991425 -1.27640001 -1.16746918 -1.0711235  -0.98562108
 -0.9094711  -0.8414078  -0.78035932 -0.72541773 -0.67581241 -0.63088744
 -0.59008261 -0.55291772]
[-2.59445803 -2.49295058 -2.29247964 -2.07935553 -1.87938603 -1.69949734
 -1.54021309 -1.39991425 -1.27640001 -1.16746918 -1.0711235  -0.98562108
 -0.9094711  -0.8414078  -0.78035932 -0.72541773 -0.67581241 -0.63088744
 -0.59008261 -0.55291772]

可読性の観点からは長い式をlambda expressionにしない方が良いと思う。

可読性の悪いコードは以下の問題を孕む:

  • 実装時にしかチェックされない
  • 実装者にしかチェックされない
  • 機能変更時にミスを誘発する

PEP8でもdefで定義するように表示される。

$ pep8 lambdaExpression_180401.py 
lambdaExpression_180401.py:14:1: E731 do not assign a lambda expression, use a def
lambdaExpression_180401.py:14:80: E501 line too long (151 > 79 characters)

link

謝辞

@shiracamus さんのコメントにてPEP8日本語訳の該当箇所を教えていただきました。

@koji-kojiro さんのコメントにてexplicit def statement, lambda expression, embedded inside a larger expressionの内容理解に役立ちました。

情報感謝です。