回答編集履歴

2

コメントへの回答追記

2023/06/13 12:01

投稿

退会済みユーザー
test CHANGED
@@ -40,3 +40,74 @@
40
40
  if np.allclose(a1, a2, atol=0.03, rtol=0):
41
41
  ```
42
42
  とするほうがよいかと思います。
43
+
44
+ #### コメントへの返信
45
+
46
+ > コードの中にある `else:`はどこにかかっているのでしょうか?
47
+ > コードのイメージはつくのですが,elseの条件が何に当たるのかが理解できません.
48
+
49
+ とのことですが、この `else`ブロックは内側のfor文を作る `for a1 in l1:` に対してオプションで付加されるもので、機能としては`for a1 in l1:`によるforループからbreakで抜けることなく、forループの最後の回が実行された後に呼ばれます。
50
+
51
+ 以下は(質問の回答とは関係のない)簡単な例です。
52
+
53
+ ```Python
54
+ for i in range(5):
55
+ print(i)
56
+ else:
57
+ print('in else block')
58
+ ```
59
+ 上記を実行すると以下のように表示されます。
60
+ > 0
61
+ > 1
62
+ > 2
63
+ > 3
64
+ > 4
65
+ > in else block
66
+
67
+ else ブロックの中の `print('in else block')` が実行されていることが分かります。
68
+
69
+ 次に forループ本体の中の`print(i)` の次の行に、「iが2だったらforループをその時点で抜ける」ため以下ように(緑色の)2行を追加します。
70
+
71
+ ```diff
72
+ for i in range(5):
73
+ print(i)
74
+ + if i == 2:
75
+ + break
76
+ else:
77
+ print('in else block')
78
+ ```
79
+ 上記を実行すると出力は
80
+ > 0
81
+ > 1
82
+ > 2
83
+ となって、elseブロックの `print('in else block')` は呼ばれていないことを確認できます。
84
+
85
+
86
+ このように for ループを書いたときに、`else:` を`for`とインデントを合わせて書くことで、このforがbreakされることなく全ループを完了した場合のみ呼ばれる処理を、このelse: の中に書くことができます。(けっこう便利です。)
87
+
88
+ 回答に書いたコードでは
89
+
90
+ ```python
91
+ def check_lists(l1, l2):
92
+ for a2 in l2:
93
+ for a1 in l1:
94
+ if np.isclose(a1, a2, atol=0.03, rtol=0).all():
95
+ break
96
+ else:
97
+ return False
98
+
99
+ return True
100
+ ```
101
+ となっていますが、内側のループ`for a1 in l1:`の中で、もし `a1` と`a2`が近似的に等しいリストであればbreakしています。なぜbreakしているかというと、外側のループで得られる `ar2` に近似的に等しいリストが、`l1`の中にあるかどうかを先頭から1つずつ確認しているわけですが、見つかった時点でその後は探す必要がないので breakさせています。
102
+
103
+ `l1` のどの子リスト `ar1` も`a2` に近似的に等しくない場合は、breakで抜けないことになり、この場合は`a2` に近似的に等しいリストが `l1`に無いので、この時点で、(つまり、それ以降の`ar2` については調べる必要なく)関数 `check_lists(l1, l2)` は `False`を返すことを決定できます。この「ある`a2`に近似的に等しい子リストが`l1`にないことが分かればその時点で即座に関数から False を返させる」処理を実現するために、`for a1 in l1:` に対する `else: `を使っています。
104
+
105
+ 公式ドキュメントでは、[4.4. break 文と continue 文とループの else 節](https://docs.python.org/ja/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops) にサンプルと説明があります。
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+

1

補足追加

2023/06/13 04:02

投稿

退会済みユーザー
test CHANGED
@@ -27,3 +27,16 @@
27
27
  とすればよいです。
28
28
 
29
29
  2つの数値 `x` と `y` が「近似的に等しい」ことの定義を修正する場合は、NumPy.iscloseメソッドのキーワード引数、rtol と atol を適宜調整します。
30
+
31
+ ---
32
+ #### 補足
33
+
34
+ BAいただいた後ですが一点補足です。上記のコードの中で
35
+ ```python
36
+ if np.isclose(a1, a2, atol=0.03, rtol=0).all():
37
+ ```
38
+ としている部分は、より目的に沿ったメソッドとして melianさんの回答にある NumPy.allclose を使って、
39
+ ```python
40
+ if np.allclose(a1, a2, atol=0.03, rtol=0):
41
+ ```
42
+ とするほうがよいかと思います。