From 163058f1f17a89a43bf832db7329dbfe69b02362 Mon Sep 17 00:00:00 2001 From: rasbt Date: Sun, 15 Jun 2014 23:23:19 -0400 Subject: [PATCH] contain method --- ...y_differences_between_python_2_and_3.ipynb | 263 +++++++++++++++++- 1 file changed, 261 insertions(+), 2 deletions(-) diff --git a/tutorials/key_differences_between_python_2_and_3.ipynb b/tutorials/key_differences_between_python_2_and_3.ipynb index 19d8a8c..a1afba9 100644 --- a/tutorials/key_differences_between_python_2_and_3.ipynb +++ b/tutorials/key_differences_between_python_2_and_3.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:7d8ee5c733199e70a4c5c71b6dfd0953ab5e6c33c6a0c7ef50dce07b4d56ae32" + "signature": "sha256:a91d66ae5e233f325b262961102505a8bdaee3ad1a251f061dee9cd68c0aaeac" }, "nbformat": 3, "nbformat_minor": 0, @@ -872,11 +872,270 @@ "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'xrange' is not defined" ] } ], + "prompt_number": 5 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "
\n", + "
\n" + ] + }, + { + "cell_type": "heading", + "level": 3, + "metadata": {}, + "source": [ + "The `__contain__` method for `range` objects in Python 3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another thing worth mentioning is that `range` got a \"new\" `__contains__` method in Python 3.x (thanks to [yegle](), who pointed this out). The `__contains__` method can speedup \"look-ups\" in Python 3.x `range` significantly for integer and bolean types.\n" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "x = 10000000" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def val_in_range(x, val):\n", + " if val in range(x):\n", + " return True\n", + " else:\n", + " return False" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 10 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def val_in_xrange(x, val):\n", + " if val in range(x):\n", + " return True\n", + " else:\n", + " return False" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "print('Python', python_version())\n", + "assert(val_in_range(x, x/2) == True)\n", + "assert(val_in_range(x, x//2) == True)\n", + "%timeit val_in_range(x, x/2)\n", + "%timeit val_in_range(x, x//2)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Python 3.3.5\n", + "1 loops, best of 3: 751 ms per loop" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "1000000 loops, best of 3: 1.21 \u00b5s per loop" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + } + ], + "prompt_number": 11 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Based on the `timeit` results above, you see that the execution for the \"look up\" was about 60,000 faster when it was of an integer type rather than a float. However, since Python 2.x's `range` or `xrange` doesn't have a `__contains__` method, the \"look-up speed\" wouldn't be that much different for integers or floats:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "print 'Python', python_version()\n", + "assert(val_in_xrange(x, x/2.0) == True)\n", + "assert(val_in_xrange(x, x/2) == True)\n", + "%timeit val_in_xrange(x, x/2.0)\n", + "%timeit val_in_xrange(x, x/2)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Python 2.7.7\n", + "1 loops, best of 3: 661 ms per loop" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "1 loops, best of 3: 564 ms per loop" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + } + ], + "prompt_number": 6 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below the \"proofs\" that the `__contain__` method wasn't added to Python 2.x yet:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "print('Python', python_version())\n", + "range.__contains__" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Python 3.4.1\n" + ] + }, + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 2, + "text": [ + "" + ] + } + ], + "prompt_number": 2 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "print 'Python', python_version()\n", + "range.__contains__" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Python 2.7.7\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'builtin_function_or_method' object has no attribute '__contains__'", + "output_type": "pyerr", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m'Python'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpython_version\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mrange\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__contains__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'builtin_function_or_method' object has no attribute '__contains__'" + ] + } + ], + "prompt_number": 7 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "print 'Python', python_version()\n", + "xrange.__contains__" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Python 2.7.7\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "type object 'xrange' has no attribute '__contains__'", + "output_type": "pyerr", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m'Python'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpython_version\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mxrange\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__contains__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: type object 'xrange' has no attribute '__contains__'" + ] + } + ], "prompt_number": 8 }, {