diff --git a/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb b/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb index 6db49ed..66e8d07 100644 --- a/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb +++ b/.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:29a120258e2d108ed5eace08e071ad866ae379b4f24fde804401ee858a2090fb" + "signature": "sha256:39951e0d86a78e2a0068b01db48a79c51e896c8f05c69e387c77e0fb68eaec41" }, "nbformat": 3, "nbformat_minor": 0, @@ -404,6 +404,10 @@ "\n", "If both values of in a `or` expression are True, Python will select the first one, and the second one in `and` expressions\n", "\n", + "Or - as a reader suggested - picture it as \n", + "`a or b == a if a else b` \n", + "`a and b == b if a else a` \n", + "\n", "(Original source: [http://gistroll.com/rolls/21/horizontal_assessments/new](http://gistroll.com/rolls/21/horizontal_assessments/new))" ] }, @@ -427,13 +431,6 @@ ], "prompt_number": 9 }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And a fun fact" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -448,7 +445,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Don't use mutable objects (e.g., dictionaries, lists, sets, etc.) as default arguments for functions! You might expect that a new list is created every time when we call the function without providing an argument for the default parameter, but this is not the case: Python will create the mutable object (default parameter) only the first time the function is called, see the following code:\n", + "Don't use mutable objects (e.g., dictionaries, lists, sets, etc.) as default arguments for functions! You might expect that a new list is created every time when we call the function without providing an argument for the default parameter, but this is not the case: Python will create the mutable object (default parameter) the first time the function is defined - not when it is called, see the following code:\n", "\n", "(Original source: [http://docs.python-guide.org/en/latest/writing/gotchas/](http://docs.python-guide.org/en/latest/writing/gotchas/)" ] @@ -599,9 +596,11 @@ "\n", "## About lambda and closures-in-a-loop pitfall\n", "\n", - "The following example illustrates how the (last) `lambda` is being reused:\n", + "Remember the [\"consuming generators\"](consuming_generators)? This example is somewhat related, but the result might still come unexpected. \n", "\n", - "(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))" + "(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))\n", + "\n", + "In the first example below, where we call a `lambda` function in a list comprehension, the value `i` is dereferenced every time we call `lambda` within the scope of the list comprehension. Since the list is already constructed when we `for-loop` through the list, it is set to the last value 4." ] }, { @@ -627,13 +626,13 @@ ] } ], - "prompt_number": 24 + "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Here, a generator can save you some pain:**" + "This, however, does not apply to generators:" ] }, { @@ -659,7 +658,7 @@ ] } ], - "prompt_number": 25 + "prompt_number": 9 }, { "cell_type": "markdown", @@ -985,7 +984,7 @@ "\n", "**A. Jesse Jiryu Davis** has a nice explanation for this phenomenon (Original source: [http://emptysqua.re/blog/python-increment-is-weird-part-ii/](http://emptysqua.re/blog/python-increment-is-weird-part-ii/))\n", "\n", - "If we try to extend the list via `+=` *\"then the statement executes STORE_SUBSCR, which calls the C function PyObject_SetItem, which checks if the object supports item assignment. In our case the object is a tuple, so PyObject_SetItem throws the TypeError. Mystery solved.\"*" + "If we try to extend the list via `+=` *\"then the statement executes `STORE_SUBSCR`, which calls the C function `PyObject_SetItem`, which checks if the object supports item assignment. In our case the object is a tuple, so `PyObject_SetItem` throws the `TypeError`. Mystery solved.\"*" ] }, { diff --git a/not_so_obvious_python_stuff.ipynb b/not_so_obvious_python_stuff.ipynb index 1ad2108..66e8d07 100644 --- a/not_so_obvious_python_stuff.ipynb +++ b/not_so_obvious_python_stuff.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:5f8052b5458fbe30e4066fd51688157e823dbbcce9f2e4ef402acfc6af40d046" + "signature": "sha256:39951e0d86a78e2a0068b01db48a79c51e896c8f05c69e387c77e0fb68eaec41" }, "nbformat": 3, "nbformat_minor": 0, @@ -404,6 +404,10 @@ "\n", "If both values of in a `or` expression are True, Python will select the first one, and the second one in `and` expressions\n", "\n", + "Or - as a reader suggested - picture it as \n", + "`a or b == a if a else b` \n", + "`a and b == b if a else a` \n", + "\n", "(Original source: [http://gistroll.com/rolls/21/horizontal_assessments/new](http://gistroll.com/rolls/21/horizontal_assessments/new))" ] }, @@ -427,13 +431,6 @@ ], "prompt_number": 9 }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And a fun fact" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -448,7 +445,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Don't use mutable objects (e.g., dictionaries, lists, sets, etc.) as default arguments for functions! You might expect that a new list is created every time when we call the function without providing an argument for the default parameter, but this is not the case: Python will create the mutable object (default parameter) only the first time the function is called, see the following code:\n", + "Don't use mutable objects (e.g., dictionaries, lists, sets, etc.) as default arguments for functions! You might expect that a new list is created every time when we call the function without providing an argument for the default parameter, but this is not the case: Python will create the mutable object (default parameter) the first time the function is defined - not when it is called, see the following code:\n", "\n", "(Original source: [http://docs.python-guide.org/en/latest/writing/gotchas/](http://docs.python-guide.org/en/latest/writing/gotchas/)" ] @@ -599,9 +596,11 @@ "\n", "## About lambda and closures-in-a-loop pitfall\n", "\n", - "The following example illustrates how the (last) `lambda` is being reused:\n", + "Remember the [\"consuming generators\"](consuming_generators)? This example is somewhat related, but the result might still come unexpected. \n", "\n", - "(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))" + "(Original source: [http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html](http://openhome.cc/eGossip/Blog/UnderstandingLambdaClosure3.html))\n", + "\n", + "In the first example below, where we call a `lambda` function in a list comprehension, the value `i` is dereferenced every time we call `lambda` within the scope of the list comprehension. Since the list is already constructed when we `for-loop` through the list, it is set to the last value 4." ] }, { @@ -627,13 +626,13 @@ ] } ], - "prompt_number": 24 + "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Here, a generator can save you some pain:**" + "This, however, does not apply to generators:" ] }, { @@ -659,7 +658,7 @@ ] } ], - "prompt_number": 25 + "prompt_number": 9 }, { "cell_type": "markdown",