测试字典键是否存在的条件始终为 False
问题描述
我创建了一个函数,它使用两个字典,curr_stats
和 weekly_result
.如果 weekly_result
中有任何键不在 curr_stats
中,则该函数应该只打印 invalid_msg
,没有 curr_stats
.
I made a function that consumes two dictionaries, curr_stats
and weekly_result
. If there are any keys in weekly_result
that aren't in curr_stats
, the function is supposed to just print invalid_msg
, with no mutation of curr_stats
.
但我的代码第 5 行的 if
语句似乎不起作用.它应该触发下一个 if
语句,因此 curr_stats
不会发生突变.
But the if
statement on the 5th line of my code doesn't seem to be working. It's supposed to trigger the next if
statement, so no mutation of curr_stats
occurs.
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 中,所有比较都有相同的优先级,包括in
.正在发生的事情是 比较链,一种旨在测试传递关系的特殊形式就像在数学课上一样:
In Python, all comparisons have the same precedence, including in
.
What's happening is comparison chaining, a special form intended to test transitive relationships like in math class:
if x_min < x < x_max:
...
作为 PawełKordowski 在他的评论中指出,上面的比较链大多相当于:
As Paweł Kordowski pointed out in his comment, the above comparison chain is mostly equivalent to:
if x_min < x and x < x_max:
...
(有一个区别:等效"代码可能会计算两次 x
,而比较链仅计算一次 x
.)
(There is one difference:
The "equivalent" code might evaluate x
twice, while the comparison chain evaluates x
exactly once.)
在您的情况下,比较链是:
In your case, the comparison chain is:
if team in curr_stats == False:
...
...(大部分)等同于:
...which is (mostly) equivalent to:
if team in curr_stats and curr_stats == False:
...
仅当 curr_stats
包含 team
并且 curr_stats
为空时才适用……这绝不应该发生.
This is only true if curr_stats
contains team
and curr_stats
is empty... which should never happen.
您的代码的问题是 == False
--- 部分是因为它将比较变成了比较链,但主要是因为您从一开始就不需要它.当你想要一个布尔值的对立面时,Python 提供了 not
关键字.您的条件语句应为:
The problem with your code is the == False
--- in part because it turned a comparison into a comparison chain, but mostly because you never needed it in the first place.
Python provides the not
keyword for when you want a Boolean's opposite.
Your conditional statement should read:
if team not in curr_stats:
invalid = invalid + 1
最后一个建议:通过去掉 invalid
计数器并在发现无效的 team
时立即返回,可以使这个函数变得更短.(一旦您发现 weekly_result
是无效输入,您可能就不会关心它是否甚至无效".)我还使用了 dict.items
简化最终的
One last suggestion:
This function can be made even shorter by getting rid of the invalid
counter and just returning as soon as an invalid team
is found.
(Once the you've discovered that weekly_result
is invalid input, you probably don't care if it's "even more invalid".)
I also used dict.items
to simplify the final for
loop:
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
相关文章