Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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?

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.