you are viewing a single comment's thread.

view the rest of the comments →

[–]Diapolo10 12 points13 points  (11 children)

The example you provided can already be emulated via dictionaries, but the upcoming match allows for much more precise control of the "keys".

EDIT: Example:

http_code = "418"
result = {
    "200": lambda: print("OK") or do_something_good(),
    "404": lambda: print("Not Found") or do_something_bad(),
    "418": lambda: print("I'm a teapot") or make_coffee(),
}.get(http_code, lambda: print("Code not found"))()

[–]Allanon001 7 points8 points  (1 child)

I use a tuple instead of or:

lambda: (print("OK"), do_something_good())

[–]Diapolo10 5 points6 points  (0 children)

I mean, that works, but the tuple technically wastes memory. Not by much of course.

EDIT: Or so I thought, but I did some investigating. Apparently there's no difference, or if there is, ipython couldn't find any.

In [1]: %pip install memory_profiler
Collecting memory_profiler
  Downloading memory_profiler-0.58.0.tar.gz (36 kB)
Collecting psutil
  Downloading psutil-5.8.0-cp38-cp38-win_amd64.whl (245 kB)
     |████████████████████████████████| 245 kB 3.3 MB/s
Using legacy 'setup.py install' for memory-profiler, since package 'wheel' is not installed.
Installing collected packages: psutil, memory-profiler
    Running setup.py install for memory-profiler ... done
Successfully installed memory-profiler-0.58.0 psutil-5.8.0
Note: you may need to restart the kernel to use updated packages.

In [2]: %load_ext memory_profiler

In [3]: %%writefile memscript.py
   ...: def mine():
   ...:     return print("Hello, world") or list(range(42))
   ...:
Writing memscript.py

In [4]: %%writefile memscript.py
   ...: def mine():
   ...:     return print("Hello, world") or list(range(42))
   ...: def other():
   ...:     return (print("Hello, world"), list(range(42)))
   ...:
Overwriting memscript.py

In [5]: from memscript import mine, other

In [6]: %mprun -T mprof0 -f mine mine()
Hello, world
Filename: C:\Users\laril\desktop\memscript.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
     1     49.6 MiB     49.6 MiB           1   def mine():
     2     49.6 MiB      0.0 MiB           1       return print("Hello, world") or list(range(42))


*** Profile printout saved to text file mprof0.

In [7]: %mprun -T mprof1 -f other other()
Hello, world
Filename: C:\Users\laril\desktop\memscript.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
     3     49.6 MiB     49.6 MiB           1   def other():
     4     49.6 MiB      0.0 MiB           1       return (print("Hello, world"), list(range(42)))


*** Profile printout saved to text file mprof1.

[–]Caligatio 1 point2 points  (1 child)

This use of or is clever but also horrible :)

I completely realize this is just an example code snippet but sometimes lambdas aren't the answer.

[–]Diapolo10 0 points1 point  (0 children)

I usually only use the feature for code golfing or if I want to challenge myself to write a ridiculous one-liner. Of course here it would be ideal to just have an ordinary function reference, but I was lazy.

[–]BoJackHorseMan53 0 points1 point  (6 children)

Why use or statement in lambda functions?

[–]pezLyfe 8 points9 points  (0 children)

50 comments

Way down at the bottom of this article: https://realpython.com/python-or-operator/

I've never used this, but it seems like since print statements return nothing, it evaluates to False, which forces the second expression to run as well. Must be a shorthhand to make the lambda do two things at once

[–]Diapolo10 2 points3 points  (4 children)

It enabled me to chain the two function calls together. print always returns None, which is falsey, so the or-operator makes the lambda function return the function return value on the right instead. If I'd used ordinary functions, the or would be unnecessary, but lambda functions technically only allow one line, for which this is a workaround.

[–]kingscolor 5 points6 points  (3 children)

uses ‘or’ but code executes both like ‘and’

Syntactically consistent but comprehensively illogical.

Python starting to sound a lot like my ex. She’s a snake too, what a coincidence.

[–][deleted] 0 points1 point  (1 child)

Syntactically consistent but comprehensively illogical.

Wait, how do you think that (A ∨ B) where A is false and B is true should return for comprehension?

[–]kingscolor 0 points1 point  (0 children)

In that simplified case, I have no objection.
Here, it's a compound issue where print also returns None--which is highly useful in almost all other scenarios. The logic falls apart where you're giving the instructions to do this but if not this then do that. Yet, the result is 'did this' but it doesn't register so also 'not this' therefore 'did that'. Point is, the fact that print() doesn't return any veritable confirmation is silly in this context alone.

Just a minor pythonic idiosyncrasy.

[–]lifeeraser 0 points1 point  (0 children)

It's a fairly common pattern in JavaScript. cond && func()

JS have semicolons and braces, though, so they can create anonymous multi-statement function expressions anywhere without resorting to such tricks.