How to express conditional execution inside lambdas Python?

What I learned:

In Dive in to Python, I read about the peculiarities of the and and or operators, and how the evaluation of short circuits of Boolean operators can be used to more accurately express conventions through and / or a trick that is very similar to the triple operator in C.

WITH

 result = condition ? a : b 

Python:

 result = condition and a or b 

This seems useful since lambda functions are limited to single-line in Python, but it uses logical syntax to express control flow.

Since Python 2.5, the built-in if seems to have come to the rescue as a more readable syntax for and / or trick:

 result = a if condition else b 

Therefore, I suppose this is a pythonic replacement for a less readable and-or-else construct. Even if I want to nest a few conditions, it still looks pretty comprehensive:

 result = a if condition1 else b if condition2 else c 

But in a world of uncertainty, I often find that I wrote such code to access abc:

 result = a and hasattr(a, 'b') and hasattr(ab, 'c') and abc or None 

So, using inline β€” if I could probably get rid of some ands and ors, which led to a quite readable piece of code:

 result = abc if hasattr(a, 'b') and hasattr(ab, 'c') else None 

I also discovered a somewhat hidden approach for conditonals in this recipe

 result = (a, b)[condition] 

but this is not short-circuited and will lead to all kinds of errors if the result of the condition does not return a boolean value of 0 or 1.

What I would like to know:

Now I wonder if it would be preferable / more pythonic to use inline- if as much as possible, if downstream compatibility is not a problem, or is it just a matter of taste and how much does it feel at home in the world of short circuit assessment?

Update

I just realized that inline-if is more than syntactic sugar for and-or-trick, as it will not fail if a is false in a boolean context. Therefore, it is probably more fault tolerant.

+4
source share
4 answers

The pythonic thing that needs to be done is to admit when you stretched your code past what is wise to squeeze into one function and just use a regular function. Remember that you cannot do anything with lambda , which cannot also be performed with a named function.

The gap for each will be different, but if you find yourself writing:

 return abc if hasattr(a, 'b') and hasattr(ab, 'c') else None 

too much, just think about it:

 try: return abc except AttributeError: return None 
+2
source

Since there is a special language construct with a built-in if - else that does what you want and that was introduced to replace ugly workarounds like the ones you mention, it is a good idea to use it. Moreover, hacks like the and - or trick usually have unexpected angular cases / errors.

In this case, the and - or trick does not work:

 a = 0 b = 1 c = True and a or b 

c will be 1 , which you do not expect if you are looking for semantics of if - else .

So, why use erroneous workarounds when there is a language construct that does exactly what you want?

+2
source

I would rather indicate what my code does. Inline if very explicitly performs conditional assignment, and readability is counted. Inline, if it didn’t hit the tongue, if and / or side effects were considered preferable.

The pep for conditional expressions describes in more detail why this particular syntax was chosen and specifically discusses and / or hacks:

http://www.python.org/dev/peps/pep-0308/

0
source

This applies to the specific case that you mentioned, but I think that in most cases, every case when you need encoded short circuit logic can be handled by a more elegant solution. This is obviously a matter of taste, let me add, so scratches if you think higher is better than this:

 try: foo = abc except AttributeError: print "woops" 

In other, less simple cases, encapsulating all tests in a function can significantly improve readability.

EDIT: by the way, duck print .

0
source

Source: https://habr.com/ru/post/1341648/


All Articles