【问题标题】:Conditional that tests for a dictionary key's presence is always False测试字典键是否存在的条件始终为 False
【发布时间】:2017-08-10 14:21:44
【问题描述】:

我创建了一个函数,它使用两个字典,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]

【问题讨论】:

标签: python dictionary conditional


【解决方案1】:

在 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

【讨论】:

    猜你喜欢
    • 2018-10-13
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多