return 1 + (n >= 10) + (n >= 100) + (n >= 1e3) + (n >= 1e4) + (n >= 1e5) + (n >= 1e6) + (n >= 1e7) + (n >= 1e8) + (n >= 1e9) ... sum(n>=10**i for i in range(100))
for (for example) inputs up to a googol. Or with your fix for the base case, 1 + sum(n>=10**i for i in range(1, 100))
Another cute way that hides the loop from itertools import count, takewhile
1 + len(list(takewhile(lambda x: 10**x <= n, count(1)))) def noloops(n):
x = lambda n, digits: (n / 1e9, digits + (n >= 10) + (n >= 100) + (n >= 1e3) + (n >= 1e4) + (n >= 1e5) + (n >= 1e6) + (n >= 1e7) + (n >= 1e8) + (n >= 1e9))
y = lambda n, digits: x(*x(*x(*x(*x(*x(n, digits))))))
return y(*y(*y(*y(*y(*y(n, 1))))))[1]
Now we have it up to 324 digits without any loops.