私は Google Python の演習を行っていますが、min() 組み込み関数の動作を理解していません。期待した結果が得られないようです。演習は「babynames」で、「baby1990.html」ファイル ( https://developers.google.com/edu/python/exercises/baby-names )を使用してコードをテストしています。
def extract_names(filename):
f = open(filename, 'r').read()
res = []
d = {}
match = re.search(r'<h3(.*?)in (\d+)</h3>', f)
if match:
res.append(match.group(2))
vals = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f)
for n, m, f in vals:
if m=='Adrian' or f=='Adrian':
if m not in d:
d[m] = n
else:
d[m] = min(n, d[m])
if f not in d:
d[f] = n
else:
print "min( "+str(n)+", "+str(d[f])+") = "+str( min(n, d[f]) )
d[f] = min( [n, d[f]] )
for name,rank in sorted(d.items()):
res.append(name+" "+str(rank))
return res
vals はタプル (rank、male_name、female_name) のリストであり、各名前 (男性と女性) を名前をキー、ランクを値として辞書 'd' に格納したいと考えています。重複がある場合は、下位のランク値を保持したい。
'Adrian' という名前がコレクションに 2 回表示されていることに気付きました。1 回目はランク 94 の男性名で、2 回目はランク 603 の女性名です。2 つの値のうち小さい方が必要です。
そのため、'Adrian' が初めて一致したとき、ランク 94 (正しく) で辞書に格納されます。2 回目に一致すると、実行フローは 2 番目の if の 2 番目の分岐に正しく入りますが、min(94, 603) = 94 であっても、結果は 603 になります。したがって、結果は次のようになります。
min( 603, 94) = 603
1990
Adrian 603
Anton 603
Ariel 94
バグがどこにあるかわかりません。インタプリタ経由で、予想どおり、min(94, 603) = 94 です。私は何が欠けていますか?
手伝ってくれてありがとう
PS: リストなしの同じ関数である min( n, d[f] ) も試しましたが、結果は常に 603 です