This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: False positive using operator 'AND' while checking keys on dict()
Type: Stage: resolved
Components: macOS Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: leonardogalani, ned.deily, ronaldoussoren, xtreak
Priority: normal Keywords:

Created on 2019-12-28 18:31 by leonardogalani, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg358954 - (view) Author: Leonardo Galani (leonardogalani) Date: 2019-12-28 18:31
using Python 3.7.6 (default, Dec 27 2019, 09:51:07) @ macOs

dict = { 'a': 1, 'b': 2, 'c': 3 }

if you `if 'a' and 'b' and 'c' in dict: print('ok')` you will get a True, since everything is true.

if you `if 'a' and 'g' and 'c' in dict: print('ok')` you also get a True because the last statement is True but the mid statement is false.

To avoid this false positive, you need to be explicit:
`if 'a' in dict and 'g' in dict and 'c' in dict: print('ok')` you will get a false.
msg358956 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2019-12-28 19:03
It's intended as non-empty strings evaluate to True so you with `'a' and 'b' and 'c' in dict` you are essentially evaluating `'a' and 'b' and ('c' in dict)` with brackets precedence i.e. `True and True and True` . On the other hand `'a' and 'g' and 'c' in dict` it's the same with 'g' evaluated to True. I guess you want to check all the keys are present where all is more readable. Some more answers here: https://stackoverflow.com/questions/1285911/how-do-i-check-that-multiple-keys-are-in-a-dict-in-a-single-pass

>>> all(char in dict for char in ['a', 'b', 'c'])
True
>>> all(char in dict for char in ['a', 'b', 'g'])
False
msg358964 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2019-12-28 20:16
P.S. You should also read the "Operator precedence" section for expressions in the Python Language Reference manual which explains that comparison operators bind tighter than Boolean AND operators:

https://docs.python.org/3/reference/expressions.html#operator-precedence
msg358965 - (view) Author: Leonardo Galani (leonardogalani) Date: 2019-12-28 20:31
I would totally agree if it wasn't for this:

>>> 'a' and 'b' and 'g' in dict
False

The last evaluation is False, making the whole statement False.

but thanks for the documentation link and stackoverflow suggestion.
it sure does make the code more readable.

Happy new year!
History
Date User Action Args
2022-04-11 14:59:24adminsetgithub: 83330
2019-12-28 20:31:46leonardogalanisetmessages: + msg358965
2019-12-28 20:16:39ned.deilysetmessages: + msg358964
2019-12-28 19:42:13serhiy.storchakasetstatus: open -> closed
resolution: not a bug
stage: resolved
2019-12-28 19:03:25xtreaksetnosy: + xtreak
messages: + msg358956
2019-12-28 18:31:50leonardogalanicreate