I started learning Python just today using Python 2.7 and I have a question here about global variables True and False:
It seems I can overwrite the value of True and False as this:
False = True
# now the value of variable False is also true.
True = False
# because the value of False is true, after this the value of True is still true.
if True(or False):
print 'xxxx'
else:
print 'yyyy'
Now wether we put True or we put False as the if condition, it always prints 'xxxx'.
Then how to recover from that fault situation? I imagine that we could use something like:
True = 1==1
False = 1!=1
but that seems bit dodgy to me. Is there any better way to do that?
Thanks.
(Also, it seems in Python 3.3 this action is no longer allowed?)
They're not "global" variables as such - they're built-ins.... They're available in __builtin__ (no s) - and you can do what you will "for a joke". Note that doing this kind of thing is mostly for mocking/profilers and things of that kin...
And no, you can't do that in the 3.x series, because True and False are keywords, not (sort of) singletons like in 2.x
The way to "recover" from this is to not let it happen.
That said, you can always use the bool() type to access True and False again. (bool() always returns one of the two boolean singletons.)
Example:
>>> bool
<type 'bool'>
>>> bool(1)
True
>>> bool(1) is bool('true')
True
>>> True = False
>>> True
False
>>> True is False
True
>>> False is bool()
True
>>> True = bool(1)
>>> True is bool(1)
True
>>> True is False
False
>>> True is bool()
False
>>> bool()
False
>>> True is bool(2)
True
>>> True is bool('true')
True
>>>
If this is a simple True = 'something' binding, then what happens is that a new name True is created in the current namespace--the __builtins__ module is not altered. In this case you can simply delete (unbind) the "True" name in your namespace. Then Python will use the one defined in __builtins__ again.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> True is __builtins__.True
True
>>> True = 'redefined'
>>> __builtins__.True is True
False
>>> del True
>>> __builtins__.True is True
True
None of this is possible in Python 3 because True and False are no longer names (variables) but keywords.
If things aren't too bad, you could set True = __builtins__.True.
Related
This question already has answers here:
Empty list boolean value
(3 answers)
Closed 4 years ago.
I am relatively new to Python and don't understand the following behavior:
Why does the statement
[] == False
evaluate to false, eventhough an empty list is falsy?
Here are more examples - in many other cases it seems that the empty list does behave in a falsy way, just not in [] == False...
>>> 0 == False # what I'd expect
True
>>> not [] # what I'd expect
True
>>> bool([]) # what I'd expect
False
>>> [] == True # what I'd expect
False
>>> [] == False # unexpected
False
>>> bool([]) == False # why does it evaluate to True again now?
True
>>> ([]) == (bool([])) # unexpected
False
>>> (not []) == (not bool([]) # apparently adding 'not' makes it behave as expected again - why?
True
Can somebody please explain this to me? How are these statements internally evaluted? I have a feeling it might be related to chaining comparisons (see e.g. here), but cannot really understand if that's correct and why.
Because falsy isn't False. Falsy just means
bool(some_object) is False
So,
>>> bool([]) is False
True
>>> bool({}) is False
True
>>> bool(0) is False
True
In Javascript, there is == operator to test if a value is falsy:
'' == false // true
In Python, == corresponds to === in Javascript, which is an exact equation (value & type).
So how to find out if a value is Falsy in Python?
You can obtain the truthiness of a value, by using the bool(..) function:
>>> bool('')
False
>>> bool('foo')
True
>>> bool(1)
True
>>> bool(None)
False
In an if statement, the truthiness is calculated implicitly. You can use the not keyword, to invert the truthiness. For example:
>>> not ''
True
>>> not 'foo'
False
>>> not 1
False
>>> not None
True
To get implicit conversion you can just use not - or (for "truthy") just use the variable in place:
if not None:
print('None')
if not False:
print('False')
if not '':
print('empty string')
if not 0:
print('zero')
if not {}:
print('empty/zero length container')
if 'hello':
print('non empty string, truthy test')
What worked was using ternary:
True if '' else False # False
More verbose than in Javascript, but works.
Even tho this question is old, but there is a not not (kinda hacky), but this is the faster than bool(..) and probably the fastest that's possible, you can do it by:
print(not not '')
print(not not 0)
print(not not 'bar')
Output:
False
False
True
I just stumbled across this and I couldn't find a sufficient answer:
x = ""
Why then is:
x == True
False
x == False
False
x != True
True
x != False
True
Am I supposed to conclude that x is neither True nor False?
to check if x is True of False:
bool("")
> False
bool("x")
> True
for details on the semantics of is and == see this question
Am I supposed to conclude that x is neither True nor False?
That's right. x is neither True nor False, it is "". The differences start with the type:
>>> print(type(""), type("x"), type(True), type(False))
builtins.str, builtins.str, builtins.bool, builtins.bool
Python is a highly object oriented language. Hence, strings are objects. The nice thing with python is that they can have a boolean representation for if x: print("yes"), e. g.. For strings this representation is len(x)!=0.
In a Boolean context, null / empty strings are false (Falsy). If you use
testString = ""
if not testString:
print("NULL String")
else:
print(testString)
As snakecharmerb said, if you pass the string to the bool() function it will return True or False based
>>> testString = ""
>>> bool(testString)
False
>>> testString = "Not an empty string"
>>> bool(testString)
True
See this doc on Truth Value Testing to learn more about this:
Python 2:
https://docs.python.org/2/library/stdtypes.html#truth-value-testing
Python 3:
https://docs.python.org/3/library/stdtypes.html#truth-value-testing
In python '==' tests for equality. The empty string is not equal to True, so the result of your comparison is False.
You can determine the 'truthiness' of the empty string by passing it to the bool function:
>>> x = ''
>>> bool(x)
False
I can't figure out why:
f = lambda x: x
In [8]: f is True
Out[8]: False
In [9]: not f is True
Out[9]: True
In [10]: f is False
Out[10]: False
In [11]: f is True
Out[11]: False
In [12]: not f
Out[12]: False
In [13]: not f is True
Out[13]: True
In [14]: not f is False
Out[14]: True
ok. So until now we can imagine that is due to the use of "is" instead of "==". As shown here:
In [15]: 0.00000 is 0
Out[15]: False
In [16]: 0.00000 == 0
Out[16]: True
Ok. But why then if i do it on the function:
In [17]: not f == False
Out[17]: True
In [18]: not f == True
Out[18]: True
In [19]: f ==True
Out[19]: False
In [20]: f ==False
Out[20]: False
In [21]: f
Out[21]: <function __main__.<lambda>>
I was trying to explain it as due to "is" instead of "==" but examples 19 and 20 crushed my logic. Can someone explain?
is tests for object identity. Comparing anything other than True with is True is always going to be false.
Your next set of tests test if not (f == False) or not (f == True); again, boolean objects only test equal against themselves, so anything other than False will test as false when comparing with == False. not False then is true.
You want to use bool() instead to test if something is true or false:
>>> bool(f)
True
>>> bool(0)
False
Don't use equality testing to see if something is true or false.
Note that only numeric 0, empty containers and strings, and False is considered false in Python. Everything else, by default, is considered true in a boolean context. Custom types can implement either the __nonzero__ method (when numeric) or the __len__ method (to implement a container) to alter that behaviour. Python 3 replaced __nonzero__ with the __bool__ method.
Functions do not have a __nonzero__ or __len__ method, so they are always considered true.
If you check the "truthyness" of a function, you will see it is True.
>>> f = lambda x: x
>>> bool(f)
True
You were simply comparing the function itself to True or False Which it would never be, since it is a function.
== checks for equivelency ... is checks identity ...
a function is a non-falsey value however it is not equivelent to True
def xyz():
pass
if xyz:
#this will trigger since a method is not a falsey value
xyz == True #No it is not equal to true
xyz == False #no it is not equal to false
xyz is True #no it certainly is not the same memory location as true
xyz is False #no it is also not the same memory location as false
Your own example shows that f is False is false so I'm confused by your title.
Why would you expect a function to evaluate as equal to either Boolean value? Wouldn't that be kind of weird behaviour?
Why is it that in Python integers and floats are, without being evaluated in a boolean context, equivalent to True? Other data types have to be evaluated via an operator or bool().
That's not True:
>>> print("True" if 1 else "False")
True
>>> print("True" if 0 else "False")
False
>>> print("True" if 0.0 else "False")
False
>>> print("True" if 123.456 else "False")
True
>>> print("True" if "hello" else "False")
True
>>> print("True" if "" else "False")
False
>>> print("True" if [1,2,3] else "False")
True
>>> print("True" if [] else "False")
False
>>> print("True" if [[]] else "False")
True
Only non-zero numbers (or non-empty sequences/container types) evaluate to True.
Here is a use case -
>>> bool(2)
True
>>> bool(-3.1)
True
>>> bool(0)
False
>>> bool(0.0)
False
>>> bool(None)
False
>>> bool('')
False
>>> bool('0')
True
>>> bool('False')
True
>>> bool([])
False
>>> bool([0])
True
In Python, these are False -
The Boolean value False itself
Any numerical value equal to 0 (0, 0.0 but not 2 or -3.1)
The special value None
Any empty sequence or collection, including the empty string('', but not '0' or 'hi' or 'False') and the empty list ([], but not [1,2, 3] or [0])
Rest would evaluate to True. Read more.
From Python Documentation 5.1:
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
None
False
zero of any numeric type, for example, 0, 0L, 0.0, 0j.
any empty sequence, for example, '', (), [].
any empty mapping, for example, {}.
instances of user-defined classes, if the class defines a __nonzero__() or __len__() method, when that method returns the integer zero or bool value False.
Why? Because it's handy when iterating through objects, cycling through loops, checking if a value is empty, etc. Overall, it adds some options to how you write code.
0 is evaluated to False.
if 0:
assert(0)