Created
June 9, 2019 03:57
-
-
Save guocheng/5ecbcaf69202624ac8e7ab563bb1402b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"This gist is a summary of the [Is there a difference between “==” and “is”?\n", | |
"](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is) thread on Stackoverflow." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Use `is` to **check identifies**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"False" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"m = 1234567\n", | |
"n = 1234567\n", | |
"m is n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Think of `is` as:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"id(m) == id(n)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Implementation Exception\n", | |
"\n", | |
"The official implementation of python is CPython, which [optimizes the storage of integers in range(-5 to 256) by making them singletons](https://docs.python.org/2/c-api/int.html#c.PyInt_FromLong). This is also true for short strings." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"m = 123\n", | |
"n = 123\n", | |
"m is n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"m = 'abc'\n", | |
"n = 'abc'\n", | |
"m is n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The code above happens due to optimization. It is NOT guaranteed to happen in other implementations. Thus, one should not expect this to happen and should not use `is` to compare values." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Use `==` to **check equality**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"m = 1234567\n", | |
"n = 1234567\n", | |
"m == n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Comparing to None\n", | |
"\n", | |
"> Comparisons to singletons like None should always be done with is or is not, never the equality operators.\n", | |
"\n", | |
"> 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!\n", | |
"\n", | |
"-- [PEP8](https://www.python.org/dev/peps/pep-0008/#programming-recommendations)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m is None\n" | |
] | |
} | |
], | |
"source": [ | |
"m = None\n", | |
"\n", | |
"if m is None: # always use is when comparing with None\n", | |
" print('m is None')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Although the following code works, it backfires in the next block. Thus, `==` should never be used to compare with `None`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m is None\n" | |
] | |
} | |
], | |
"source": [ | |
"m = None\n", | |
"\n", | |
"if m == None: # Althought it works, don't do it (see the sectin below)\n", | |
" print('m is None')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Checking variable is None (The WRONG WAY)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m is None\n" | |
] | |
} | |
], | |
"source": [ | |
"m = list() # empty container\n", | |
"\n", | |
"if m: # will always evaluate to false in an if statement\n", | |
" print('m is not None')\n", | |
"else:\n", | |
" print('m is None')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m is None\n" | |
] | |
} | |
], | |
"source": [ | |
"m = dict() # empty container\n", | |
"\n", | |
"if m: # will always evaluate to false in an if statement\n", | |
" print('m is not None')\n", | |
"else:\n", | |
" print('m is None')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m is None\n" | |
] | |
} | |
], | |
"source": [ | |
"m = set() # empty container\n", | |
"\n", | |
"if m: # will always evaluate to false in an if statement\n", | |
" print('m is not None')\n", | |
"else:\n", | |
" print('m is None')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"When the variable is an empty container (any object that holds an arbitrary number of other objects), and it is used in a `if` statement, it always evaluates to `False`." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### The Correct way to check for None (always spell out the is not None part, don't be lazy)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"m is not None\n" | |
] | |
} | |
], | |
"source": [ | |
"m = [] # m is not None, it is just an empty list\n", | |
"\n", | |
"if m is not None:\n", | |
" print('m is not None')\n", | |
"else:\n", | |
" print('m is None')" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment