例:最大値を求める関数
Pythonで整数のリストの最大値を求める関数を自作する場合を考えてみる。
これまでの最大値とリストの各整数を比較し、最大値より大きい場合は最大値を更新する関数を作成すればよいわけだが、型ヒントを使う場合、最大値の初期値が問題になってくる。
最大値を0
と置く方法
my_max.py
def my_max(nums: List[int]) -> int:
mx: int = 0
for num in nums:
if num > mx:
mx = num
return mx
リストがすべて負の数からなっていた場合、0
が返ってきてしまうという問題がある。
sys.maxsize
を使う方法
my_max2.py
def my_max2(nums: List[int]) -> Optional[int]:
mx: int = -sys.maxsize - 1
for num in nums:
if num > mx:
mx = num
return mx
sys.maxsize
はPy_ssize_t型の変数が取りうる最大値を示す整数1であって無限大ではないため、メモリの許す限りより大きな数が存在してしまうという問題がある。
最大値をfloat('inf')
やmath.inf
と置く方法
my_max3.py
def my_max3(nums: List[int]) -> int:
mx: int = float('-inf') # mx: int = -math.inf でも同じ
for num in nums:
if num > mx:
mx = num
return mx
整数int型に浮動小数点float型を代入することができないため、Pylanceやmypyの型チェックでエラーになる。
Union型を使う方法
my_max4.py
def my_max4(nums: List[int]) -> Union[int, float]:
mx: Union[int, float] = float('-inf')
for num in nums:
if num > mx:
mx = num
return mx
浮動小数点float型を許容してしまうという問題がある。
Optional型を使う方法
my_max5.py
def my_max5(nums: List[int]) -> Optional[int]:
mx: Optional[int] = None
for num in nums:
if not mx or num > mx:
mx = num
return mx
None型を許容してしまうという問題と条件式がやや長くなるという問題がある。