3

I came across following code while solving this problem:

f=lambda n:"a"[n:]or f(n-1)+chr(97+n)+f(n-1)

The function generates abacaba sequence of specific depth n

For example:

n = 2, output: 'abacaba'

n = 3, output: 'abacabadabacaba'

The question is, how does the code work? Namely, how does "or" operator work inside lambda? (I assume code above uses recursion, and to my knowledge, normally we use loops for recursion, but I don't see anything that resembles loops in the code above)

Community
  • 1
  • 1
iwbtrs
  • 358
  • 4
  • 13
  • I think that the `or` is used to terminate the recursion. – quamrana Jul 05 '19 at 19:22
  • `or` is lazy - if left side gives `True` then there is no need to run right side because `True or anything` always gives `True`. This way it returns result from left side if it can be converted to `True` or it returns result from right side if left side gives `False`. In similar way ca be used **and**. – furas Jul 05 '19 at 19:24

2 Answers2

3

It works the same way it does anywhere else. If the left-hand argument of or is truthy, the expression evaluates to that; otherwise, it evaluates to the right-hand argument. In this case, "a"[n:] is the empty string when n > 0, so it's equivalent to

def f(n):
    if n == 0:
        return "a"
    else:
        return f(n-1) + chr(97+n) + f(n-1)
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Why did he put [n:] after a? I mean, why would this version: f=lambda n:"a" or f(n-1)+chr(97+n)+f(n-1) not work properly? – iwbtrs Jul 05 '19 at 19:46
  • 1
    @Nelver: *In this case, `"a"[n:]` is the empty string when `n > 0`*. It returns the right side of the `or` when `n > 0`, and then when `n == 0` it produces `"a"` and the right side doesn’t run. – Ry- Jul 05 '19 at 19:51
  • @Ry-♦ So If I get this correctly, empty string evaluates to False? – iwbtrs Jul 05 '19 at 19:53
  • 1
    @Nelver: Yep. Try `bool("")`. Lots of other types override `__bool__`, too; for example, the number zero and empty lists/dicts/sets are all falsy. – Ry- Jul 05 '19 at 19:56
0

Let's break it down.

f = lambda # declare a variable f that is a function
n:         # that takes an int parameter 'n'
"a"[n:]    # if n is 0 return 'a'
or         # else
f(n-1)     # return a recursive call at n - 1
+          # plus
chr(97+n)  # character from code 97 + n
+          # plus
f(n-1)     # another recursive call
Jared Smith
  • 19,721
  • 5
  • 45
  • 83