Tuesday 23 January 2018 — This is almost seven years old, but it's still good.
One of the things that has made Python successful is its readability. Code is clear and easy to understand. One of the reasons is that Python uses words for a few things that other languages use symbols for. But sometimes the readability is misleading. Beginners construct valid Python expressions that don’t do what they seem like they should do.
Let’s say you want to know if your variable x is equal to 17. You could do:
if x is 17:
This might work. But then if you try:
if name is "Ned":
it doesn’t work? What!? Why not? It’s so clear.
The problem is that “is” doesn’t check two values for equality, it checks if the left and right side are precisely the same object. But you can have two different string objects, each of which has the value “Ned”. You don’t use “is” to check equality, you use “==”:
if name == "Ned":
It’s not just strings: numbers can also do surprising things:
>>> 1000 + 1 is 1001
False
“x is 17” is more English-like than “x == 17”, but it isn’t right. This is one time that Python’s famed readability leads you to the wrong construct.
Another example: you need to know if the answer was either “y” or “yes”, so you try this:
if answer == "y" or "yes":
print("Thanks")
and now your program doesn’t work. No matter what answer is, it prints “Thanks.” Why?
The “or” operator is for combining boolean (true/false) expressions. The result is true if either of its operands is true. So your code is equivalent to:
if (answer == "y") or ("yes"):
print("Thanks")
If answer is “y”, then the if will be true. If answer isn’t “y”, then the or will consider the right-hand side, “yes”. Strings are true if they are not empty, so “yes” is always true. So the if condition will always be true, no matter what value answer has.
The right ways to do this are:
if answer == "y" or answer == "yes":
print("Thanks")
or if you want to be fancier,
if answer in {"y", "yes"}:
print("Thanks")
(a list or a tuple would also work here instead of a set, though then you get into philosophical debates about how many data structures fit on the head of a pin.)
Don’t get me wrong, I agree that Python is very readable. And every language has constructs that seem like they should work, but don’t. You have to study well, and be careful to use your chosen language properly.
Comments
The second case I will leave without a comment, this is programming basics and you definitely need to learn more about Python if you think in 'if a == 1 or 2' constructions.
if "y" in answer: print("Thanks")
@Boris, Ned Batchelder is a real polite guy in answering you. He has a 16,100 score on Stackoverflow, what's yours?
Calling it out as a problem specifically in Python feels weird.
I am newbie so please go easy if I am mis-understanding what you say. When I tried this, here's what I get:
>>> 100+1 is 101
True
>>> 1000 + 1 is 1001
False
>>> 1000+1 is 1001
False
>>> 100+1 is 101
True
>>> 100 + 1 is 101
True
>>> name = "ted"
>>> name is "ted"
True
>>>
How is this happening?
I am using python 3.6.2
The mechanics behind how Python decides to make new integers, and when to reuse old integer objects, is complex, implementation- and version-dependent, and changes depending on seemingly irrelevant details, like whether you are in the repl or a .py file. If you are interested in implementation trivia, the Stack Overflow question I linked to earlier in the comments includes details.
Don't get me wrong: I think Python's readability is one of its strongest points. Other languages will seem more foreign to new learners. Sure, beginners try things in other languages, and they don't work as they expect, but it's not because they typed out some English and it didn't work like English.
Yes, it's not as trivial to write correct Python code as one would think.
But the real advantage of Python is its readability: Given clean, idiomatic code someone with some programming background but no knowledge of that specific language will find it is much easier to understand Python than say, Perl, C++, Haskell.
Add a comment: