
{"id":5250,"date":"2025-04-29T22:50:30","date_gmt":"2025-04-30T02:50:30","guid":{"rendered":"https:\/\/ikriv.com\/blog\/?p=5250"},"modified":"2025-04-29T22:50:30","modified_gmt":"2025-04-30T02:50:30","slug":"python-assignment-in-lambdas-take-2-use-tuples-and-operator","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=5250","title":{"rendered":"Python: assignment in lambdas, take 2. Use tuples and operator :="},"content":{"rendered":"<p>This is a follow up on <a href=\"https:\/\/ikriv.com\/blog\/?p=4971\">this post<\/a>.<\/p>\n<p>Default parameters are not the only way to do complex calculations in Python lambdas. Another idea is to use tuples and the &#8220;walrus&#8221; operator <code>:=<\/code> available since Python 3.8. E.g., if we want to calculate (x<sup>2<\/sup> + 2x + 7) + sqrt(x<sup>2<\/sup> + 2x + 7), we can write a lambda as follows:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nmymath = lambda x: (\r\n    y := x**2 + 2*x + 7,\r\n    y + sqrt(y)\r\n)&#x5B;-1]\r\n<\/pre>\n<p>Credit goes to &#x1F464;<b><font color=\"navy\">fleming<\/font><\/b> for suggesting this brilliant option.<\/p>\n<p>Let&#8217;s dissect what we are doing here:<\/p>\n<ol>\n<li>The lambda creates a tuple.<\/li>\n<li>The tuple has two items.<\/li>\n<li>The first item creates a variable named <code>y<\/code> and assigns a value.<\/li>\n<li>The second item uses this variable.<\/li>\n<li>Finally, the lambda returns the last item for the tuple by applying the <code>[-1]<\/code> index.<\/li>\n<\/ol>\n<p>Let&#8217;s consider a more interesting example:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\ndelete_file = lambda file_path: (\r\n    os := __import__(&#039;os&#039;),\r\n    exists := os.path.exists(file_path),\r\n    os.remove(file_path) if exists else None,\r\n    exists\r\n)&#x5B;-1]\r\n\r\n# create a test file\r\ntest_file = &quot;\/tmp\/testfile&quot;\r\nwith open(test_file, &quot;w&quot;) as file:\r\n    file.write(test_file)\r\n    \r\nprint(delete_file(test_file)) # prints True\r\nprint(delete_file(test_file)) # prints False\r\n<\/pre>\n<p>This code imports <code>os<\/code> module and deletes a file, all within a lambda.<\/p>\n<p>With some ingenuity, we can do loops in a lambda and execute conditionals. Consider this implementation of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fizz_buzz\">Fizzbuzz game<\/a>:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfizzbuzz = lambda max_value: (\r\n        f15 := lambda n: &quot;fizzbuzz&quot; if n%15 == 0 else None,\r\n        f5 := lambda n: &quot;fizz&quot; if n%3 == 0 else None,\r\n        f3 := lambda n: &quot;buzz&quot; if n%5 == 0 else None,\r\n        get_str := lambda n: f15(n) or f5(n) or f3(n) or str(n),\r\n        loop := (print(get_str(n)) for n in range(1,max_value+1)), # deferred loop\r\n        &#x5B;x for x in loop if False] # execute the deferred loop, discarding all values\r\n    )&#x5B;-1]\r\n\r\nfizzbuzz(15) # prints 1, 2, fizz, 4, buzz, ...\r\n<\/pre>\n<p>The only thing you can&#8217;t really do in a lambda is to catch exceptions. This would work if we had a built-in function similar to this:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\ndef do(f):\r\n    try:\r\n        return f(), None\r\n    except Exception as e:\r\n        return None, e\r\n<\/pre>\n<p>Alas, there is no such function. <a href=\"https:\/\/docs.python.org\/3\/library\/contextlib.html#contextlib.suppress\"><code>contextlib.suppress()<\/code><\/a> comes tantalizingly close, but it requires a <code>with<\/code> statement, and we can&#8217;t have <code>with<\/code> statements in a lambda either. Of course, we could define such function using <code>exec()<\/code>, but then we could define <i>any<\/i> function using <code>exec()<\/code> and the whole point of doing things in a lambda would be moot.<\/p>\n<p>Why does it matter what we can run in a lambda? It has to do with safety of <code>eval()<\/code>, which we&#8217;ll discuss next. Or at least at some point in the future. I have a draft post about it that has been lying around for a few months, and I intend to publish it soon.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a follow up on this post. Default parameters are not the only way to do complex calculations in Python lambdas. Another idea is to use tuples and the <a href=\"https:\/\/ikriv.com\/blog\/?p=5250\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[26],"tags":[],"class_list":["entry","author-ikriv","post-5250","post","type-post","status-publish","format-standard","category-python"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5250"}],"version-history":[{"count":7,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5250\/revisions"}],"predecessor-version":[{"id":5257,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5250\/revisions\/5257"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}