not None test in Python [duplicate] - python

This question already has answers here:
Python `if x is not None` or `if not x is None`? [closed]
(9 answers)
Closed 8 years ago.
Out of these not None tests.
if val != None:
if not (val is None):
if val is not None:
Which one is preferable, and why?

if val is not None:
# ...
is the Pythonic idiom for testing that a variable is not set to None. This idiom has particular uses in the case of declaring keyword functions with default parameters. is tests identity in Python. Because there is one and only one instance of None present in a running Python script/program, is is the optimal test for this. As Johnsyweb points out, this is discussed in PEP 8 under "Programming Recommendations".
As for why this is preferred to
if not (val is None):
# ...
this is simply part of the Zen of Python: "Readability counts." Good Python is often close to good pseudocode.

From, Programming Recommendations, PEP 8:
Comparisons to singletons like None should always be done with is or is not, never the equality operators.
Also, beware of writing if x when you really mean if x is not None — e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
PEP 8 is essential reading for any Python programmer.

The best bet with these types of questions is to see exactly what python does. The dis module is incredibly informative:
>>> import dis
>>> dis.dis("val != None")
1 0 LOAD_NAME 0 (val)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 3 (!=)
6 RETURN_VALUE
>>> dis.dis("not (val is None)")
1 0 LOAD_NAME 0 (val)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 9 (is not)
6 RETURN_VALUE
>>> dis.dis("val is not None")
1 0 LOAD_NAME 0 (val)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 9 (is not)
6 RETURN_VALUE
Notice that the last two cases reduce to the same sequence of operations, Python reads not (val is None) and uses the is not operator. The first uses the != operator when comparing with None.
As pointed out by other answers, using != when comparing with None is a bad idea.

Either of the latter two, since val could potentially be of a type that defines __eq__() to return true when passed None.

Related

Does this way of swapping values in list use extra memory in Python?

The usual way to swap values in a list is to use a temporary variable.
temp = l[i]
l[i] = l[j]
l[j] = temp
But in python you can do this:
l[i], l[j] = l[j], l[i]
How does this second method work? Is it the exact same process? Does it use less / more memory?
import dis
def swap_using_temp(a, b):
temp = a
a = b
b = temp
def swap_using_unpacking(a, b):
a, b = b, a
swap_using_unpacking does not require extra memory.
Explanation:
If you disassemble the code using dis module of both the function described then you will see that in swap_using_unpacking there is a bytecode instruction ROT_TWO which swaps the 2 topmost elements of the stack(which don't require a third variable hence no extra memory is consumed).
dis.dis(swap_using_unpacking)
11 0 LOAD_FAST 1 (b)
2 LOAD_FAST 0 (a)
4 ROT_TWO
6 STORE_FAST 0 (a)
8 STORE_FAST 1 (b)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
dis.dis(swap_using_temp)
5 0 LOAD_FAST 0 (a)
2 STORE_FAST 2 (temp)
6 4 LOAD_FAST 1 (b)
6 STORE_FAST 0 (a)
7 8 LOAD_FAST 2 (temp)
10 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
14 RETURN_VALUE
You are asking the wrong question here. You are not using assembly language but Python, so you should not worry for some extra bytes. What really matters in Python is readability.
Anyway, both versions should be internally implemented more or less the same way, except that the first one creates an additional identifier. It is explicitely named temp so provided you do not use it in that scope, it brings no real problem.
If you use a linting environment that warns you for possible problems (what you should do...) you must be aware that reusing a variable name that hides the same name in an outer scope, while perfectly correct on a language point of view will light some warning on. But as you should not use a temp identifier outside a local scope (readability...) it should not be a problem either.
So it is more of a matter of taste. If you or your team mates often use other languages that do not allow multiple assignments the first way will be more natural. If you mainly use Python, the second way is IMHO more pythonic because it avoids adding an unnecessary identifier in the local scope. But as I have already said, nothing more that a matter of taste...

Why is True if foo else False faster then bool(foo)?

Why is it that according to the timeit.timeit function the code boolean = True if foo else False runs faster than the code boolean = bool(foo)?
How is it that the if statement is able to determine the trueness of foo faster then the bool function itself?
Why doesn't the bool function simply use the same mechanic?
And what is the purpose of the bool function when it can be outperformed by a factor of four by a different technique?
Or, is it so that I am misusing the timeit function and that bool(foo) is, in fact, faster?
>>> timeit.timeit("boolean = True if foo else False", setup="foo='zon-zero'")
0.021019499999965774
>>> timeit.timeit("boolean = bool(foo)", setup="foo='zon-zero'")
0.0684856000000309
>>> timeit.timeit("boolean = True if foo else False", setup="foo=''")
0.019911300000103438
>>> timeit.timeit("boolean = bool(foo)", setup="foo=''")
0.09232059999999365
Looking at these results, True if foo else False seems to be four to five times faster than bool(foo).
I suspect that the difference in speed is caused by the overhead of calling a function and that does indeed seem to be the case when I use the dis module.
>>> dis.dis("boolean = True if foo else False")
1 0 LOAD_NAME 0 (foo)
2 POP_JUMP_IF_FALSE 8
4 LOAD_CONST 0 (True)
6 JUMP_FORWARD 2 (to 10)
>> 8 LOAD_CONST 1 (False)
>> 10 STORE_NAME 1 (boolean)
12 LOAD_CONST 2 (None)
14 RETURN_VALUE
>>> dis.dis("boolean = bool(foo)")
1 0 LOAD_NAME 0 (bool)
2 LOAD_NAME 1 (foo)
4 CALL_FUNCTION 1
6 STORE_NAME 2 (boolean)
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
According to the dis module, than the difference between the two techniques is:
2 POP_JUMP_IF_FALSE 8
4 LOAD_CONST 0 (True)
6 JUMP_FORWARD 2 (to 10)
>> 8 LOAD_CONST 1 (False)
versus
0 LOAD_NAME 1 (bool)
4 CALL_FUNCTION 1
which makes it look like either the call to a function is far too expensive for something as simple as determining a boolean value or the bool function has been written very inefficiently.
But that actually makes me wonder why anyone would use the bool function when it is this much slower and why the bool function even exists when python does not even seem to use it internally.
So, is the bool function slower because it has been written inefficiently, because of the function overhead, or because of a different reason?
And why would anyone use the bool function when a much faster and equally clear alternative is available?
As per Python documentation :
class bool( [ x ] )
Return a Boolean value, i.e. one of True or False. x is converted using the standard truth testing
procedure. If x is false or omitted, this returns False; otherwise it returns True. The bool class is a
subclass of int (see Numeric Types — int, float, complex). It cannot be subclassed further. Its only
instances are False and True
So, when you directly use the object itself (like foo), the interpreter uses its foo.__bool__ property. But the bool function is a wrapper that again calls foo.__bool__
As you said, calling the function made it expensive.
And the use of bool is, there are certain situations where you need the boolean value of an object and need to refer it by a variable.
x = bool(my_object)
Writing x = my_object doesn't work.
Here its useful.
Sometimes bool(foo) is more readable where you can ignore small time lags.
You might be also interested in knowing that
x = {}
is faster than
x = dict()
Find out why... :)

Behavior of python method in absence of return statement [duplicate]

This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 9 years ago.
I have a question related to change in program behavior
the absence of return statement leads to in a python method.
The count method below prints number of digits in a given integer.
With the below chunk of code I get the result as 4, which is
the expected result.
def count(x,acc=0):
if x==0:
return acc
return count(x/10,acc+1)
print "Count is %s" %(count(1234))
Result: Count is 4
If I modify the above method so that the last statement does not contain
the 'return' statement the result I get is 'None'.
def count(x,acc=0):
if x==0:
return acc
count(x/10,acc+1)
print "Count is %s" %(count(1234))
Result: Count is None
(The version of Python I used is: 2.7.3)
Does the above behavior results due to the fact that Python doesn't do tail call optimization or is there any other reasoning involved ?
A similar chunk of code in perl (which AFAIK doesn't do tail call optimization) provides
the expected result without 'return' being part of the last statement.
sub counter {
my ($n,$acc) = #_;
return $acc if ($n==0);
counter(int($n/10), $acc+1);
}
print "Count is:" . counter(1234,0) ."\n"
Result: Count is:4
(The versions of Perl I ran above code chunk are : 5.14.4 and 5.8.5).
My questions are:
Is Tail Call optimization the reason for the behavior shown in above chunk of Python code.
If that were the case then why behavior of perl code differs, which doesn't do TCO either.
Doesn't have to do with the missing of tail optimization at all. Functions in Python need the keyword return explicitly, otherwise is assumed their return None.
I know Ruby doesn't behave that way, it returns the value of the last executed expression. With Perl it must be the same.
It is nothing that clever, just the fact that Python programs behave that way :)
See the disassembly for both Python functions. You may see how the one having the return value actually calls the function and return the value on top of the stack. The one that doesn't have it, see that have two instructions after the funciont call, which load constant None and return it.
def count(x,acc=0):
if x==0:
return acc
return count(x/10,acc+1)
def count2(x,acc=0):
if x==0:
return acc
count(x/10,acc+1)
In [7]: import dis
In [8]: dis.dis(count)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (0)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 16
3 12 LOAD_FAST 1 (acc)
15 RETURN_VALUE
4 >> 16 LOAD_GLOBAL 0 (count)
19 LOAD_FAST 0 (x)
22 LOAD_CONST 2 (10)
25 BINARY_DIVIDE
26 LOAD_FAST 1 (acc)
29 LOAD_CONST 3 (1)
32 BINARY_ADD
33 CALL_FUNCTION 2
36 RETURN_VALUE
In [9]: dis.dis(count2)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (0)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 16
3 12 LOAD_FAST 1 (acc)
15 RETURN_VALUE
4 >> 16 LOAD_GLOBAL 0 (count)
19 LOAD_FAST 0 (x)
22 LOAD_CONST 2 (10)
25 BINARY_DIVIDE
26 LOAD_FAST 1 (acc)
29 LOAD_CONST 3 (1)
32 BINARY_ADD
33 CALL_FUNCTION 2
36 POP_TOP
37 LOAD_CONST 0 (None)
40 RETURN_VALUE
Without the return, the only case where your return something if when acc == 0; for any other call to your count recursive method, you don't return anything, hence the None received.
Unlike other languages (scala, apparently perl as well, probably others), python does not return the last statement by default, you have to call return explicitely.
Tail call elimination does not prevent Perl's semantics (though without Perl semantics, you'd have far fewer tail calls since every function would implicitly end with return;). It's purely a language design choice. The reason Perl and Python differ is that they weren't designed by the same people.
The syntax for returning a value varies by language simply due to choice. The designers of Python opted to require an explicit return statement. In QBasic, you had to assign the value to return to a variable that shared the same name as the function.
Functions in Python without a return statement return the value None.
In this case, you are only returning a value when x == 0, therefore the None that you get. Check the Python tutorial for more info: http://docs.python.org/2/tutorial/controlflow.html#defining-functions

How does tuple unpacking differ from normal assignment? [duplicate]

This question already has answers here:
The `is` operator behaves unexpectedly with non-cached integers
(2 answers)
What's with the integer cache maintained by the interpreter?
(1 answer)
"is" operator behaves unexpectedly with integers
(11 answers)
Closed 1 year ago.
From this link I learnt that
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object
But when I tried to give some example for my session and I found out that it behaves differently with assignment and tuple unpacking.
Here is the snippet:
>>> a,b = 300,300
>>> a is b
True
>>> c = 300
>>> d = 300
>>> c is d
False
Because int is immutable, Python may or may not use exists object, if you save the following code in to a script file, and run it, it will output two True.
a, b = 300, 300
print a is b
c = 300
d = 300
print c is d
When Python compile the code, it may reuse all the constants. Becasue you input your code in a python session, the codes are compiled line by line, Python can't reuse all the constants as one object.
The document only says that there will be only one instance for -5 to 256, but doesn't define the behavior of others. For immutable types, is and is not is not important, because you can't modify them.
import dis
def testMethod1():
a, b = 300, 300
print dis.dis(testMethod1)
Prints:
4 0 LOAD_CONST 2 ((300, 300))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 0 (a)
9 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE None
def testMethod2():
a = 300
b = 300
Prints:
7 0 LOAD_CONST 1 (300)
3 STORE_FAST 0 (a)
8 6 LOAD_CONST 1 (300)
9 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE None
So, it looks essentially the same, but with LOAD_CONST in one step in the first method and two steps in the second method....
EDIT
After some testing, I discovered that both methods return False eventually; however, on one run only, ie not putting the methods in a loop, they seem to always return True. Sometimes it uses a single reference, and sometimes it does not.
The documentation only states that -5 to 256 will return the same reference; hence, you simply just shouldn't be using is for comparison (in this case) as the number's current id has no guarantee on it.
NB: You never want to use is for comparison of values, as that's not what it's for, it's to compare identities. My point was that is's return value is not always going to be True when you're outside of the defined range.

"x not in y" or "not x in y"

When testing for membership, we can use:
x not in y
Or alternatively:
not x in y
There can be many possible contexts for this expression depending on x and y. It could be for a substring check, list membership, dict key existence, for example.
Are the two forms always equivalent?
Is there a preferred syntax?
They always give the same result.
In fact, not 'ham' in 'spam and eggs' appears to be special cased to perform a single "not in" operation, rather than an "in" operation and then negating the result:
>>> import dis
>>> def notin():
'ham' not in 'spam and eggs'
>>> dis.dis(notin)
2 0 LOAD_CONST 1 ('ham')
3 LOAD_CONST 2 ('spam and eggs')
6 COMPARE_OP 7 (not in)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> def not_in():
not 'ham' in 'spam and eggs'
>>> dis.dis(not_in)
2 0 LOAD_CONST 1 ('ham')
3 LOAD_CONST 2 ('spam and eggs')
6 COMPARE_OP 7 (not in)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> def not__in():
not ('ham' in 'spam and eggs')
>>> dis.dis(not__in)
2 0 LOAD_CONST 1 ('ham')
3 LOAD_CONST 2 ('spam and eggs')
6 COMPARE_OP 7 (not in)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> def noteq():
not 'ham' == 'spam and eggs'
>>> dis.dis(noteq)
2 0 LOAD_CONST 1 ('ham')
3 LOAD_CONST 2 ('spam and eggs')
6 COMPARE_OP 2 (==)
9 UNARY_NOT
10 POP_TOP
11 LOAD_CONST 0 (None)
14 RETURN_VALUE
I had thought at first that they always gave the same result, but that not on its own was simply a low precedence logical negation operator, which could be applied to a in b just as easily as any other boolean expression, whereas not in was a separate operator for convenience and clarity.
The disassembly above was revealing! It seems that while not obviously is a logical negation operator, the form not a in b is special cased so that it's not actually using the general operator. This makes not a in b literally the same expression as a not in b, rather than merely an expression that results in the same value.
No, there is no difference.
The operator not in is defined to have the inverse true value of in.
—Python documentation
I would assume not in is preferred because it is more obvious and they added a special case for it.
They are identical in meaning, but the pycodestyle Python style guide checker (formerly called pep8) prefers the not in operator in rule E713:
E713: test for membership should be not in
See also "Python if x is not None or if not x is None?" for a very similar choice of style.
Others have already made it very clear that the two statements are, down to a quite low level, equivalent.
However, I don't think that anyone yet has stressed enough that since this leaves the choice up to you, you should
choose the form that makes your code as readable as possible.
And not necessarily as readable as possible to anyone, even if that's of course a nice thing to aim for. No, make sure the code is as readable as possible to you, since you are the one who is the most likely to come back to this code later and try to read it.
In Python, there is no difference. And there is no preference.
Syntactically they're the same statement. I would be quick to state that 'ham' not in 'spam and eggs' conveys clearer intent, but I've seen code and scenarios in which not 'ham' in 'spam and eggs' conveys a clearer meaning than the other.

Categories

Resources