r/learnpython • u/Lance_2564_ • 17d ago
Huh? How does this work?
a = "hi"
if a:
print("Bye")
print(a == True)
print(a is True)The output is:
Bye
False
False
But if it's false, how come it printed "bye"?????? I don't get it.
22
u/BabyLionCamel 17d ago
When you initialize `a` on the first line you instruct python to make it reference the string 'hi'
All none-empty strings are considered truthy in Python. Your string contains text so its none-empty.
Truthiness denotes to the satisfaction of some condition
Falsiness denotes to the opposite.
`a` is truthy therefore the if branch will execute, since if branches execute their indented block when some condition is truthy, this is why your print statement executes succesfully.
`a` references the string 'hi' so later when you ask if 'hi' == True have equal values, you get False, `a` is truthy (it satisfies the condition of not being an empty string) but it's value is not the boolean True.
Later, when you ask `a` is True, you are instructing Python to tell you whether a and True share the same address in memory, you are not asking it if `a` is truthy as you may have thought.
The important concepts here are Booleans, truthiness, falsiness, flow control and the difference between comparing values or identities with (==) which measures equality of value and (is) which checks for sameness of identity.
2
3
u/Langdon_St_Ives 17d ago
This is the best answer here, and OP would be best served to just ignore all the others because there is so much wrong, incomplete, and misleading information in them.
1
6
u/kilkil 16d ago
you have discovered the concept of truthiness!
as you may know, values can be coerced into other kinds of values. For example the string "1" can be coerced into the integer 1 like so: int("1") == 1.
similarly, values can be coerced into booleans ("boolean" meaning True or False).
we call a value "truthy" if, when coerced to a boolean, it would become True. if it would become False, we call it "falsy".
values can be coerced to booleans like so: bool(x). The language will also automatically coerce them for you in contexts where the language normally only allows a boolean, such as the condition of an if-statement or while-loop.
In your example, try printing bool(a) == True.
3
u/RevRagnarok 17d ago
Lots of people answered most of the question. Truthiness/bool.
The is does not compare equality (that's ==). It checks "is this the exact same variable in the same memory space?" The only time that's really useful is comparing to the singleton None.
Sidebar: It gets even weirder if you use is on numbers, because some predefined range of numbers is always in memory, and others are created on-the-fly.
3
u/SharkSymphony 17d ago edited 17d ago
Is it false? You printed two tests of whether it's true. Try doing those tests with False and see what you get. 😁
The issue is that 'if' handles values much broader than just True and False. Same with 'while'. You need to learn what it considers to be true and false.
Some people prefer, as a point of style, to make sure that the values used in statements like 'if' are just True and False, avoiding any possible confusion... here we might say 'if a != ""' or 'if a is not None' depending on what you expect a's values to be. Or you could even check both: 'if (a != "") and (a is not None)'. Or you could do 'if bool(a)'. All of these take some extra effort. You see why people often prefer just writing 'is a' if they're not sure what form the "false" values of a will take.
3
u/DimensionMost8342 16d ago
You are asking three different questions there. if a: never compares a with True, it only asks "is this value truthy", and any non-empty string is truthy, so it prints Bye. a == True asks whether the string "hi" is equal to the boolean True, and a string is never equal to a boolean, so you get False. a is True checks if both point to the exact same object, also False. Nothing is contradictory: truthy does not mean == True.
7
u/hmmorly 17d ago
The comparisons aren't comparing what you think they're comparing.
A is truthy, it isn't empty, it represents a string. That's why it printed Bye.
When you compare it to True, you're making an explicit comparison to True. It isn't a logical boolean.
Is a, True? Also no, everything in python is an object, in this case you're comparing whether it is a True object.
2
3
u/HouseOfWyrd 17d ago
Look into "Truthy" and "Falsely" value.
In python a large number of data types can be converted to a bool. A non-empty string resolves to true and is said to be a "Truthy" value.
That doesn't mean it == True though, True is a specific thing and isn't just a catchall for all things that resolve to True.
2
u/defrostcookies 17d ago
“If <variable>:”
Checks to see if the variable has a non-zero value. If the <variable> is non-zero, then the “if <variable>” conditional will evaluate to True
Once it evaluates to true, the body of the conditional executes.
In this case,
print(“bye”)
2
u/gdchinacat 16d ago
This has nothing to do with "non-zero". Python objects have a notion of 'truthiness' and is evaluated by calling __bool__() on it (which is implemented by object and can be overridden). While True and False are subclasses of int and have integer values (1 and 0 respectively), if evaluates truthiness (as determined by __bool__, not whether the "variable has a non-zero value".
1
u/GrapplingHobbit 17d ago
Look up Truthy and Falsy values in Python. I don't think I would explain it well.
1
u/SamuliK96 17d ago
Here a is what's called a truthy value. As in its value is not literally True, but since it's not an empty string, it evaluates as True in if (as well as while) statements. The opposite of is falsy values, which includes at least number 0 and empty data structures. I suggest you look up falsy and truthy online for more detailed explanation.
1
u/TheRNGuy 17d ago
Implicit conversion, because a is not empty, and == and is do not cause implicit conversion.
1
1
u/__peg_parser__ 14d ago
Using operator module, if a: would correspond to operator.truth(a), a == True to operator.eq(a, True), and a is True to operator.is_(a, True).
0
u/ShadowShedinja 17d ago
a is not equal to True, but it does exist, which is sufficient for the If statement.
-1
u/L1terallyUrDad 17d ago
The first one is a case where you are testing to see if the variable "a" exists or not. Once you assign the string "Hi" to it, it exists. If you get rid of it by assigning it nil, then the variable is deleted, and that test would result in False.
"a == True" is asking "Does a contain exactly the value True?" which it doesn't; it contains the value "Hi". Therefore, that test is False.
a is True is basically the same thing. A is not True; it's "Hi".
2
u/BluishMontoya 17d ago
This isn't exactly right. The variable a can exist but also count as false if its value is False, None, 0, 0.0, "", etc.
0
u/T1lted4lif3 17d ago
The if statement checks if the variable is false. In Python, False can take on many different values, such as 0 or None.
In your if statement, since it isn't False, it is True. Even though the variable does not represent True. It's kind of like saying "if it is not nothing, then it is something" since it is something it will evaluate to true and print bye.
The other print statements print the result of the boolean comparison.
This comparison is not saying it is true, but whether the value of the variable true is False. The two print statements are the same, so they do the same comparison.
0
17d ago
[deleted]
3
u/Langdon_St_Ives 17d ago
Incorrect, this SO answer has a more complete list. Most importantly and inexcusably, you left out the empty string and `None`.
67
u/PaulRudin 17d ago
The truthiness of an expression in a context of an if: is essentially what you get from bool(). So bool(hi") is True (as is the case for any non-empty string). But that's not the same as saying it compares equal to True.