以下のように数値以外の値が混入した二次元のリストから行ごとの平均値を算出し一次元のリストにその平均値を格納するプログラムを作成しています。
python
1li_2d = [[1, 2, 3, 4], 2 [1, 3, 5.5, 7], 3 [1, 2.5, 3, 'a'], 4 ['a', 3, 5, None]]
数値以外の値(文字列やNone)がある行はもちろんエラーになってしまうためIllegal
やNot Number
など計算できなかったことを示す文字列を平均値の代わりに入れたいです。
以上のことを踏まえて下のようなプログラムを作成してみましたが、フラグ変数を利用しているためコードが少し長くなってしまいました。
- 行ごとに平均値を算出するプログラム
python
1import statistics 2 3 4def is_num(val) -> bool: 5 return isinstance(val, int) or isinstance(val, float) 6 7 8def average_2d(li_2d: list) -> list: 9 result = [] 10 for li in li_2d: 11 li_1d_temp = [] 12 flag_skip = False 13 for elem in li: 14 if is_num(elem): 15 li_1d_temp.append(elem) 16 else: 17 result.append('illegal') # ここの文字はなんでもいい。でも何か文字は入れたい 18 flag_skip = True 19 break 20 if not flag_skip: 21 result.append(statistics.mean(li_1d_temp)) 22 return result 23
- 使用例
python
1if __name__ == '__main__': 2 li_2d_no1 = [[1, 2, 3, 4], 3 [1, 3, 5.5, 7], 4 [1, 2.5, 3, 'a'], 5 ['a', 3, 5, None]] 6 7 li_2d_no2 = [[1, 2, 3, 4, 5, 6], 8 [None, 3, 5, 7, 9, 11], 9 [1.5, 2.5, 3, 4, 5, 6.5]] 10 print('No1', average_2d(li_2d_no1)) 11 print('No2', average_2d(li_2d_no2)) 12
result
1No1 [2.5, 4.125, 'illegal', 'illegal'] 2No2 [3.5, 'illegal', 3.75]
これでも一応期待通りに動くのでそのまま利用してもいいのですが、できればもっとスマートな方法で綺麗なコードにしたいです。
なにか他にいい方法はないでしょうか。
######補足
- 実際に利用するときはかなり長いリストを使う可能性があるので実行速度が遅くなるような例外処理は使いたくありません。
- リストではなくNumpy配列でも大丈夫です。
######環境
python3.8.5
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/07 14:14 編集