有条件地测试字典密钥的存在总是为假

时间:2017-03-19 08:22:45

标签: python dictionary conditional

我创建了一个消耗两个词典curr_statsweekly_result的函数。如果weekly_result中的任何键都不在curr_stats中,则该函数应该只打印invalid_msg,而不会突变curr_stats

但是我的代码第5行的if语句似乎并没有起作用。它应该触发下一个if语句,因此不会发生curr_stats的变异。

def update_standings(curr_stats, weekly_result):
    invalid = 0
    point_counter(weekly_result)
    for team in weekly_result:
        if team in curr_stats == False:
            invalid = invalid + 1
    if invalid > 0:
        print(invalid_msg)
    else:
        for team in weekly_result:
            curr_stats[team] = curr_stats[team] + weekly_result[team]

1 个答案:

答案 0 :(得分:0)

在Python中,all comparisons have the same precedence,包括in。 正在发生的是comparison chaining,这是一种用于测试数学课程中传递关系的特殊形式:

if x_min < x < x_max:
    ...

正如PawełKordowski在his comment中所指出的,上述比较链大部分相当于:

if x_min < x and x < x_max:
    ...

(有一点不同: “等效”代码可能会评估x两次,而比较链只评估x一次。)

在您的情况下,比较链是:

if team in curr_stats == False:
    ...

...(大部分)相当于:

if team in curr_stats and curr_stats == False:
    ...

仅当curr_stats包含team curr_stats为空时才会出现这种情况......这种情况永远不会发生。

你的代码的问题是== False ---部分是因为它将比较转变为比较链,但主要是因为你从来没有首先需要它。 当你想要一个布尔相反的时候,Python提供not关键字。 您的条件语句应为:

if team not in curr_stats:
    invalid = invalid + 1

最后一个建议: 通过删除invalid计数器可以使此功能更短,并且只要找到无效的team就返回。 (一旦你发现weekly_result是无效输入,你可能不在乎它是否“更多无效”。) 我还使用dict.items来简化最终的for循环:

def update_standings(curr_stats, weekly_result):
    point_counter(weekly_result)
    for team in weekly_result:
        if team not in curr_stats:
            print(invalid_msg)
            return
    for team, result in weekly_result.items():
        curr_stats[team] += result