## understanding the logic behind len()

This is the place for queries that don't fit in any of the other categories.

### understanding the logic behind len()

Hi

I am new to coding and I have been given an example of a function similar to the built in function len().

I do understand

def fct(s) :
if not s : return 0
return 1 + fct(s[1:])

However I am having a hard time understanding the logic of the one below which is the equivalent for what I see.

def fct(s) : return s and 1 + fct(s[1:]) or 0 #I do not understabd the "return s" part

could someone explain that to me?

Many thanks
Last edited by micseydel on Sun Oct 27, 2013 7:43 am, edited 1 time in total.
Reason: Locked op.
jean

Posts: 3
Joined: Sun Oct 27, 2013 6:30 am

### Re: understanding the logic behind len()

Try this:

Code: Select all
`def myfunct(inputx):    return True and inputxprint myfunct(5)`

You'll see the True is not returned.

s is only True if it has items. Otherwise the 0 is returned.
simongcx

Posts: 2
Joined: Sat Oct 26, 2013 12:41 pm

### Re: understanding the logic behind len()

I think it's an uglier way to write
Code: Select all
`return 1 + fct(s[1:]) if s else 0`
Due to the reasons discussed here we will be moving to python-forum.io on October 1, 2016.

This forum will be locked down and no one will be able to post/edit/create threads, etc. here from thereafter. Please create an account at the new site to continue discussion.

micseydel

Posts: 3000
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

### Re: understanding the logic behind len()

Hi, Thank you for your adices, this will be useful.

However my real concern here is that I want to understand the logic behind this coding:

def fct(s) : return s and 1 + fct(s[1:]) or 0

someone could explain what happens step by step "behind the scene" with that function?

Many thanks
jean

Posts: 3
Joined: Sun Oct 27, 2013 6:30 am

### Re: understanding the logic behind len()

jean wrote:Hi, Thank you for your adices, this will be useful.

However my real concern here is that I want to understand the logic behind this coding:

def fct(s) : return s and 1 + fct(s[1:]) or 0

someone could explain what happens step by step "behind the scene" with that function?

Many thanks

It's pretty ugly code and you should probably read another book or follow another class.
"a and b" returns b when bool(a) is true and a when bool(a) is false
"a or b" returns a when bool(a) is true and b when bool(a) is false.

bool(a) is generally true when a is not empty or zero. It's defined differently on each datatype.

That means the code is equivalent to:
Code: Select all
`def fct(s):    if bool(s):        # the if below never fails        if bool(1 + fct[s[1:]]):            return 1 + fct[s[1:]])        else:            return 0    else:        return 0`
Join the #python-forum IRC channel on irc.freenode.net!
Somelauw

Posts: 82
Joined: Tue Feb 12, 2013 8:30 pm

### Re: understanding the logic behind len()

"
Code: Select all
`some_condition and something or something_else`
" is in fact a typical and well-known Python idiom.
It is analogous to C/C++ operator "?":
Code: Select all
`condition ? answer1 : answer2;a > c ? a : c; // returns the maximum of (a,c)`

It works like this (in Python):
a) If some_condition is True (or a non-zero number or a non-empty string): the result is "something";
b) otherwise, it is yet_something_else.

For example:
Code: Select all
`>>> s = "aaa"; print s and 18 or 9918>>> s = ""; print s and 18 or 9999`

So in your case it:
1) tests if s is empty;
2) if yes , it returns 0;
3) if not, it returns 1 + whatever is the result of fct for the s except its first character.

This effectively calculates the length of the string and teaches you recursion (fct calls itself with the slightly different argument several times).
ochichinyezaboombwa

Posts: 203
Joined: Tue Jun 04, 2013 7:53 pm

### Re: understanding the logic behind len()

Thanks a lot ochichinyezaboombwa for your detailed answer. I am still trying to get my head around the logic of this line but it makes a little bit more sense now.
jean

Posts: 3
Joined: Sun Oct 27, 2013 6:30 am

### Re: understanding the logic behind len()

Maybe let's try harder. The idiom
Code: Select all
`condition and res1 or res2`
works the way it works because of the way operators "and" and "or" work.

In operator "and", both its left part and its right part matter; both must become True to make the whole thing True.

For example:
Code: Select all
`>>> True and TrueTrue>>> True and FalseFalse>>> False and "Whatever"False`

Now what's tricky about it is the following: the operator and starts with calculating its left part 1st, AND if its value is False it doesn't even bother to look at the 2nd (right) part. Indeed, why bother? The condition "Both must be True" is already broken, so the result of the whole expression is already known. Python (and most languages) make a smart decision here to avoid doing totally unnecessary calculations.
To illustrate:

Code: Select all
`>>> def foo(x):...     print "I am in foo, my arg is ", x... >>> foo(5)I am in foo, my arg is  5>>> >>> False and foo(5)False`
Notice how in the 2nd call ("False and foo(5)") foo() was NOT called at all!!!

The operator "or" works the opposite way: if its left side is not True it might still be OK: the right part gets calculated and the overall result of "or" depends on it.

Now, to confuse you a little more: there is the VALUE of operators and or or (as there is the value of any expression).
Namely, the value of operations like and or or is... what was calculated last. To illustrate (with the same foo() as above):
Code: Select all
`>>> s = "">>> print repr(s and foo(5))''>>> s = "ABC">>> print repr(s and foo(5))I am in foo, my arg is 5None`

I use repr() here because otherwise we wouldn't see anything after the 1st call: it prints the empty string s''; importantly, foo was not called. In a case s == "ABC", however, foo() does get called and what is printed as the overall result is whatever foo returns (and we know it returns nothing, or None).

Now I hope it should be clear what you should expect from the following and why:
Code: Select all
`>>> s = "">>> print repr(s and "Foo" or "Bar")>>> s = "ABC">>> print repr(s and "Foo" or "Bar")`

And this is basically identical to your return statement.

Did it help at all?
ochichinyezaboombwa

Posts: 203
Joined: Tue Jun 04, 2013 7:53 pm