Python 2.7 - min内置函数无法按预期工作

时间:2013-07-26 12:24:39

标签: python dictionary min built-in

我正在进行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'这个名字在集合中出现了两次,第一次作为男性名字排名第94位,第二次作为女性排名第603位,我想要两个值中较小的一个。

因此,第一次'Adrian'匹配时,它存储在排名为94(正确)的字典中。当它第二次匹配时,执行流程正确地进入第二个if的第二个分支,但结果为603,即使min(94,603)= 94。 结果是:

min( 603, 94) = 603
1990
Adrian 603
Anton 603
Ariel 94

我不明白这个bug在哪里。通过解释器,min(94,603)= 94,如预期的那样。我错过了什么?

感谢您的帮助

PS:我也试过了     min(n,d [f]) 这是没有列表的相同函数,但结果总是603

1 个答案:

答案 0 :(得分:5)

您正在比较字符串,不是数字:

>>> min('603', '94')
'603'

Lexographically,'6''9'之前排序。正则表达式适用于字符串,即使数字匹配,返回的匹配也是字符串。使用int()将字符串转换为整数:

vals = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f)
for n, m, f in vals:
    n = int(n)
    # ...

尝试调试Python代码时,请使用repr()代替str()来检测类型问题;如果您使用repr(),您会看到'94'将被打印而不是94(所以使用引号来表示字符串)。