数値を要素とする2つのリストa1
とa2
が近似的に等しいことの判定には、NumPyの
numpy.isclose(a1, a2)
を使うと楽かと思います。
質問にある状況の場合、
- 2つの数値
x
と y
が「近似的に等しい」ことの定義を例えば「x
とy
の差の絶対値が0.03以下である」として、
list2
に含まれる子リストのどれも、それと近似的に等しいリストが list1
の中に含まれるかどうかを判定する
のであれば、下記のような関数
python
1import numpy as np
2
3def check_lists(l1, l2):
4 for a2 in l2:
5 for a1 in l1:
6 if np.isclose(a1, a2, atol=0.03, rtol=0).all():
7 break
8 else:
9 return False
10
11 return True
を作っておいて
python
1check_lists(list1, list2) # => True
とすればよいです。
2つの数値 x
と y
が「近似的に等しい」ことの定義を修正する場合は、NumPy.iscloseメソッドのキーワード引数、rtol と atol を適宜調整します。
補足
BAいただいた後ですが一点補足です。上記のコードの中で
python
1if np.isclose(a1, a2, atol=0.03, rtol=0).all():
としている部分は、より目的に沿ったメソッドとして melianさんの回答にある NumPy.allclose を使って、
python
1if np.allclose(a1, a2, atol=0.03, rtol=0):
とするほうがよいかと思います。
コメントへの返信
コードの中にある else:
はどこにかかっているのでしょうか?
コードのイメージはつくのですが,elseの条件が何に当たるのかが理解できません.
とのことですが、この else
ブロックは内側のfor文を作る for a1 in l1:
に対してオプションで付加されるもので、機能としてはfor a1 in l1:
によるforループからbreakで抜けることなく、forループの最後の回が実行された後に呼ばれます。
以下は(質問の回答とは関係のない)簡単な例です。
Python
1for i in range(5):
2 print(i)
3else:
4 print('in else block')
上記を実行すると以下のように表示されます。
0
1
2
3
4
in else block
else ブロックの中の print('in else block')
が実行されていることが分かります。
次に forループ本体の中のprint(i)
の次の行に、「iが2だったらforループをその時点で抜ける」ため以下ように(緑色の)2行を追加します。
diff
1for i in range(5):
2 print(i)
3+ if i == 2:
4+ break
5else:
6 print('in else block')
上記を実行すると出力は
0
1
2
となって、elseブロックの print('in else block')
は呼ばれていないことを確認できます。
このように for ループを書いたときに、else:
をfor
とインデントを合わせて書くことで、このforがbreakされることなく全ループを完了した場合のみ呼ばれる処理を、このelse: の中に書くことができます。(けっこう便利です。)
回答に書いたコードでは
python
1def check_lists(l1, l2):
2 for a2 in l2:
3 for a1 in l1:
4 if np.isclose(a1, a2, atol=0.03, rtol=0).all():
5 break
6 else:
7 return False
8
9 return True
となっていますが、内側のループfor a1 in l1:
の中で、もし a1
とa2
が近似的に等しいリストであればbreakしています。なぜbreakしているかというと、外側のループで得られる ar2
に近似的に等しいリストが、l1
の中にあるかどうかを先頭から1つずつ確認しているわけですが、見つかった時点でその後は探す必要がないので breakさせています。
l1
のどの子リスト ar1
もa2
に近似的に等しくない場合は、breakで抜けないことになり、この場合はa2
に近似的に等しいリストが l1
に無いので、この時点で、(つまり、それ以降のar2
については調べる必要なく)関数 check_lists(l1, l2)
は False
を返すことを決定できます。この「あるa2
に近似的に等しい子リストがl1
にないことが分かればその時点で即座に関数から False を返させる」処理を実現するために、for a1 in l1:
に対する else:
を使っています。
公式ドキュメントでは、4.4. break 文と continue 文とループの else 節 にサンプルと説明があります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/06/13 02:00
2023/06/13 09:47
退会済みユーザー
2023/06/13 12:02
2023/06/13 12:04