and test_dict[key] == 'spam': will only be evaluated if if key in test_dict is True , it will behave exactly like your first code in which you have an attached file.
When you use and , both sides of the expression must be true, so if key in test_dict returns False, then the code will have a short circuit.
Using your and approach is actually most efficient, especially if the left side of the expression is False:
In [13]: d = {k:k for k in range(10000)} In [14]: timeit 99999 in d and d[100] == "foo" 10000000 loops, best of 3: 48.2 ns per loop In [15]: timeit d.get(9000) == "foo" 10000000 loops, best of 3: 155 ns per loop In [16]: timeit 100 in d and d[100] == "foo 10000000 loops, best of 3: 119 ns per loo In [17]: timeit d.get(100) == "foo" 10000000 loops, best of 3: 141 ns per loop
source share