回答編集履歴
2
コメントへの回答追記
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
補足追加
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
|
+
とするほうがよいかと思います。
|