Unexpected behavior from Python - python

I'm new to Python and I am a bit confused with the way Python treats an empty object.
Consider this code piece;
a = {}
if a:
print "a is alive!"
else:
print "a is NOT alive!"
if not a:
print "NOT a!"
else:
print "a!"
if a is None:
print "a is None!"
else:
print "a is NOT None!"
I get the following output for this code piece.
a is NOT alive!
NOT a!
a is NOT None!
Edit::
I am under the assumption that an object initialized by {} is a Valid Object. Why doesn't Python treat it that way? and why do I get diff output for diff If conditions?
Edit 2::
In C++, when I say
Object obj;
if (obj){
}
It will enter the IF block if obj is NOT NULL(regardless if it is garbage value or whatever)
But the same thing when I translate to python.
a = {} #This is a valid object
if a:
# Doesn't work!
Why? and I read Python evaluates {} as False. Why is that?

Empy dict/sets/lists etc are evaluated as false. None is its own type, with only one possible value.
https://docs.python.org/2.4/lib/truth.html Tells you what is evaluated as true and false

I see nothing weird in your output.
Let's go step-by-step:
a is dictionary, more specifically a dictionary object;
a is a dictionary, but it's empty, so its truth value is False
Therefore:
The first if, since a is False, prints the else statement and that's right;
The second if, since not a evaluates to True because a is False, prints the if part and that's right too.
Last, but not least a is not a None object, but a dict object, so it's right too that the else part is taken and printed.

It is a valid python object, but it is empty, so it is treated as a False, the same goes for lists [] or numbers 0. You do have a dict, but it is not a None object.

with
a = {}
you are creating an dictionary object which is not NoneType you can
check the class of your object with
type(a)
which will give you:
type dict
if not a:
will return False if a has already any members and True if a is just and empty list

Related

How return value of QCheckBox? [duplicate]

I came across a strange behaviour of python comparing a string with True/False.
I thought that python would print in the following:
if "Test" == True:
print("Hello1")
but it does not.
So I wrote some Test cases and I do not understand some of them.
if "Test" == True:
print("Hello1")
if "Test" == False:
print("Hello2")
#This I understand
if bool("Test") == True:
print("Hello3")
#This I understand too
if bool("") == False:
print("Hello4")
if "Test":
print("Hello5")
Output
>> Hello3
>> Hello4
>> Hello5
So I do not understand:
If Hello1 is not printed why is not Hello2 either?
Why does Hello5 get printed, is the cast to bool("Test") made implicit?
In the first two comparisons, you are checking whether the string "Test" has the same value as the object True or False. This is a value comparison.
If they have a different type, the comparison will return False. You can see this also when comparing lists, numbers etc.: [1]==1 (false), (1,)==[1] (false).
In the third and fourth comparisons, you are still doing a value comparison, but since both sides are of the same type (boolean), it will compare the values.
Hello5 is printed because it is not the null string "". You can see this by trying "Test" != None, which returns True.
While it is a comparison to None when it comes to most classes(None is Python's null value), Python's standard data types are compared to their "null" value, which are:
The empty string "" for strings,
[] for lists (similary () for tuples, {} for dictionaries),
0 for ints and floats,
just like a boolean comparison. Therefore it is not wrong to think of if expression as an implicit cast to if bool(expression).
What is going on under the hood is the evaluation of the __non-zero__(python2.x) or __bool__(python3.x) method of the class.
In the case of Hello1, Hello2 and Hello5 there is an object comparison and not boolean comparions.
That means that
the string-object "Test" is not the same as object True ("Hello1")
the string object "Test" is not the same as object False("Hello2")
but the string object "Test" is not None ("Hello5")

Python - if not condition returning None

This is another question from https://stackoverflow.com/questions/41028828/python-does-if-not-statement-implicitly-check-2-conditions?noredirect=1#comment69265422_41028828
I am trying to further clarify the concept with ifstatement using not.
My understanding is that print secondFunction(True) will return True since randomFunction will be called but the script is returning None. Please help!
def randomFunction(value):
if value:
return True
else:
return False
def secondFunction(v):
if not randomFunction(v):
return "minus it"
print secondFunction(True)
"randomFunction" returns True to "secondFunction". At this point you have this "if" condition:
if not (True):
If it would be "True" condition was verified and "secondFunction" returns "minus it". In your example it will never enter inside the "if" condition. For this reason "secondFunction" will always return None result because it has became implicitly a procedure without a return.
I hope that was clearly to you.

Python print None

I'm having trouble with print None as a value.
Suppose here's my python code:
def a(b):
b = None
print b
def c(a):
if a:
return True
else:
return False
>>> a(1)
None # I need this "None" to show.
>>> c(a(1))
None # I don't want to print out this, but don't know how.
False
My problem is I have to "print" the None when only calling function a.
And when I pass function a to function c, I don't want the "None" to print out.
If I type "return None", Python shell will not show "None" for function a. That's why I thought I can only use "print" if I want to show the "None". But when I pass function a to function c, the "None" also gets printed out. Is there a way to only get the result secretly without printing out the "None" in the 2nd function?
I hope my question is making sense.
Thank you very much for your help.
The call c(a(1)) will execute a(1) first and then c(a(1)). Since here a(1) is not returning true, c(a(1)) will evaluate to False.
That's the reason you get following:
None
False
Try calling the function as c(a) this will return as follows:
True
This happens because a has not executed and it is having some value to it.
Hope this helps!

Check for initialized variable in Python

I'm new to Python and I'm playing a bit with some code snippets.
In my code I need to check for variable initialization and I was using this idiom:
if my_variable:
# execute some code
but reading some posts I found this other idiom is used:
if my_variable is not None:
# execute some code
Are they equivalent or is there some semantic difference?
Quoting Python documentation on boolean operations,
In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False, None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true.
So, if my_variable will fail, if my_variable has any of the above mentioned falsy values where as the second one will fail only if my_variable is None. Normally the variables are initialized with None as a placeholder value and if it is not None at some point of time in the program then they will know that some other value has been assigned to it.
For example,
def print_name(name=None):
if name is not None:
print(name)
else:
print("Default name")
Here, the function print_name expects one argument. If the user provides it, then it may not be None, so we are printing the actual name passed by the user and if we don't pass anything, by default None will be assigned. Now, we check if name is not None to make sure that we are printing the actual name instead of the Default name.
Note: If you really want to know if your variable is defined or not, you might want to try this
try:
undefined_variable
except NameError as e:
# Do whatever you want if the variable is not defined yet in the program.
print(e)
No if 0 would be False where if my_variable was actually 0 then if my_variable is not None: would be True, it would be the same for any Falsey values.
In [10]: bool([])
Out[10]: False
In [11]: bool(0)
Out[11]: False
In [12]: bool({})
Out[12]: False
In [13]: [] is not None
Out[13]: True
In [14]: 0 is not None
Out[14]: True
It's worth noting that python variables cannot be uninitialised. Variables in python are created by assignment.
If you want to check for actual uninitialisation, you should check for (non) existence, by catching the NameError exception.
Taking an example of a null string i.e. '' which is not None
>>> a = ""
>>> if a:
... print (True)
...
>>> if a is not None:
... print (True)
...
True
>>>
And a boolean value
>>> a = False
>>> if a:
... print (True)
...
>>> if a is not None:
... print (True)
...
True
>>>
Thus they are not equivalent
Check if variable exists is in globals dict, if not initialize variable.
if 'ots' not in globals():
ots=0.0

Why python designed as str(None) return 'None' instead of an empty string?

In some other languages I knows, the intuitive result of a null to string conversion should be an empty string.
Why Python is designed to make 'None' be sort of special string?
And this can lead to extra work when checking a return value from a function
result = foo() # foo will return None if failure
if result is not None and len(str(result)) > 0:
# ... deal with result
pass
if str(None) returns empty string, the code could be shorter:
if len(str(result)) > 0:
# ... deal with result
pass
Looks like Python is trying to be verbose, to make log files be more understandable?
Checking if a string has characters in it by checking len(str(result)) is definitely not pythonic (see http://www.python.org/dev/peps/pep-0008/).
result = foo() # foo will return None if failure
if result:
# deal with result.
pass
None and '' coerce to the boolean False.
If you are really asking why str(None) does return 'None', then I believe it is because it is necessary for three-valued logic. True, False and None can be used together to determine if a logical expression is True, False or cannot be decided. The identity function is the easiest for representation.
True -> 'True'
False -> 'False'
None -> 'None'
The following would be really weird if str(None) was '':
>>> or_statement = lambda a, b: "%s or %s = %s" % (a, b, a or b)
>>> or_statement(True, False)
'True or False = True'
>>> or_statement(True, None)
'True or None = True'
>>> or_statement(None, None)
'None or None = None'
Now, if you really want for an authoritative answer, ask Guido.
If you really want to have str(None) give you '' please read this other question: Python: most idiomatic way to convert None to empty string?
Basically, because an empty string isn't a representation of None. None is a special value that is distinct from an empty string or anything else. As described in the docs, str is supposed to
Return a string containing a nicely printable representation of an object.
Basically, str is supposed to return something printable and human-readable. An empty string would not be a readable representation of None.

Categories