0

Is there a way to convert this:

if counts:
    def a(l):
        return a_with_counts(l)
else:
    def a(l):
        return a_without_counts(l)

into a ternary expression?

I tried something like this

def a(l):
    return a_with_counts(l) if counts else a_without_counts(l)

but I do not want the if counts to be evaluated each time I call a(l), I want to do it once in the beginning of my method and then evaluate directly the assigned function each time I call a(l). Is this possible?

Thank you!

mkserge
  • 93
  • 4

2 Answers2

5

You could achieve that by defining a closure as follows:

def gen_a(counts):
    return a_with_counts if counts else a_without_counts

a = gen_a(counts)

This is equivalent to writing

a = a_with_counts if counts else a_without_counts

if you only intend to call this once.

jhansen
  • 1,096
  • 1
  • 8
  • 17
  • Aha! Thank you, this is exactly what I need. I have to admit this wouldn't have crossed my mind! – mkserge Oct 26 '18 at 21:23
3

with a ternary in a lambda ?

a = lambda counts:a_with_counts if counts else a_without_counts

then

a(True)   # or False

will create a_with_counts (resp a_without_counts) function that you can call.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • you don't need a lambda to do this ... `a = (a_with_counts if counts else a_without_counts)(*args)` – Skandix Oct 26 '18 at 13:29
  • 1
    Named lambdas :S – roganjosh Oct 26 '18 at 13:29
  • 3
    Do note the Python [PEP 8 style guide](https://www.python.org/dev/peps/pep-0008/#programming-recommendations]) *Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.* – Parfait Oct 26 '18 at 13:29
  • @Parfait interesting. lambda are designed to remain anonymous. The sole interest here is to one-line define them. But jhansen answer (that I upvoted BTW) does that with a simple function. – Jean-François Fabre Oct 26 '18 at 13:32
  • 1
    @Skandix OP doesn't want to evaluate `counts` every time – Jean-François Fabre Oct 26 '18 at 13:33
  • 1
    damn I feel guilty about the `lambda` now because of you :) – Jean-François Fabre Oct 26 '18 at 13:35
  • I wasn't aware that you weren't aware they go against PEP8, thought you'd get my reference :) I'm not sure exactly what situation it avoids other than obscurity – roganjosh Oct 26 '18 at 13:36
  • well, I have some dark areas :) PEP talks about confusing tracebacks... thanks for your comments. duly noted. _must not use lambda, must not use lambda_ – Jean-François Fabre Oct 26 '18 at 13:37
  • @Jean-FrançoisFabre: ok, leave it with `a_gen = a_with_counts if counts else a_without_counts`, without the call. still no lambda needed (meanwhile this is jhansen's answer) – Skandix Oct 26 '18 at 13:39
  • 1
    It has been well mentioned on StackOverflow: see [here](https://stackoverflow.com/a/25010243/1422451), [here](https://stackoverflow.com/a/45790434/1422451), and [here](https://stackoverflow.com/a/50091199/1422451) – Parfait Oct 26 '18 at 13:41
  • damn I have read only 85% of the posts. Guess those ones went below the radar. – Jean-François Fabre Oct 26 '18 at 13:50
  • @Jean-FrançoisFabre, thanks I tried that, but ran into the same PEP warning :) Although it did not cross my mind that I can assign a name to the output of a(True) and use that afterwards :) – mkserge Oct 26 '18 at 21:34