The problem with computing a radix using a non-imperative style of programming is you need to calculate a list of successive quotients, each new entry being the quotient of the last entry divided by the radix. The problem with this is (short of using despicable hacks like log) there is no way to know how many divisions an integer will take to reduce to 0.
I'm fine with doing this with a generator :
def rep_div(n,r):
while n != 0:
yield n
n /= r
But I don't like this for some reason. I feel there must be a clever way of using a lambda, or some functional construction, without building a list like is done here :
def rep_div2(n,r):
return reduce(lambda v,i: v+[v[-1]/r],question_mark,[n])
Once the repeated divisions can be generated radix is easy :
def radix2(n,r):
return map(lambda ni: ni % r,(x for x in rep_div(n,r)))
So my question is : is it possible to rewrite rep_div
as a more concise functional construction, on one line?
1 Answer 1
From my perspective, I'd say use the generator. It's concise and easily readable to most people familiar with Python. I'm not sure if you can do this in a functional sense easily without recreating some of the toolkit of functional programming languages. For example, if I wanted to do this in Haskell (which I am by no means an expert in, so this may be a horrible way for all I know), I'd do something like:
radix :: Int -> Int -> [Int]
radix x n = takeWhile (> 0) $ iterate (\z -> z `div` n) x
You can certainly recreate takeWhile
and iterate
, however, this only works due to lazy evaluation. The other option is, as you've said, using log
and basically recreating scanl
:
def scanl(f, base, l):
yield base
for x in l:
base = f(base, x)
yield base
def radix(n, r):
return scanl(operator.__floordiv__, n, (r for x in range((int)(log(n, r)))))
So my answer is going to be "No" (predicated on the fact that someone smarter than me will probably find a way). However, unless you are playing Code Golf, I'd again suggest sticking with the generator version.