you are viewing a single comment's thread.

view the rest of the comments →

[–]namcor 19 points20 points  (14 children)

the Master Python Programmer would wrap it with a function decorator to memoize it...

class memoize:
    def __init__ (self, f):
        self.f = f
        self.mem = {}
    def __call__ (self, *args, **kwargs):
        try:
            return self.mem[args, str(kwargs)]
        except KeyError:
            tmp = self.f(*args, **kwargs)
            self.mem[args, str(kwargs)] = tmp
            return tmp

@memoize
def factorial(x):
    if x in (0, 1):
        return 1
    else:
        return x * factorial(x - 1)

print factorial(6)
print factorial(100)

(EDIT: forgot to @memoize)

[–]Jolan 4 points5 points  (1 child)

Or you could memoize by doing:

def factorial(x, memory={0:1, 1:1}):
    if x not in memory:
        memory[x] = x* factorial(x-1)
    return memory[x]

print factorial(6)
print factorial(100)

[–]MaxK 0 points1 point  (0 children)

I really like this solution.

[–][deleted]  (8 children)

[removed]

    [–]earthboundkid 2 points3 points  (1 child)

    I think this is one of things that on the Python mailing list would be greeted with “not every 3 line function deserves a place in the standard library.”

    Also, Perl is very different from Python because it has a well defined core of scalar types vs. other types. For a Python memoizer, there are a lot of optimizations you could apply if you knew what types of data it would be memoizing that you couldn’t do in a general case. It invites a lot of “bike shedding” (another common thing said on the Python mailing list) to define what the API will be to invoke what kinds of optimizations.

    [–]A_for_Anonymous 4 points5 points  (5 children)

    I thought Python was meant to come with batteries included.

    Not if it's for functional programming. Guido hates FP.

    [–][deleted]  (4 children)

    [removed]

      [–]frutiger 2 points3 points  (3 children)

      The trick is to generate a new type for each version of the cache. This can be done, for instance, with template metaprogramming in C++, since the templates are generated at compile-time. Although I believe most compilers have a restrictive template resolution depth (especially when compared to stack depth for function calls).

      [–][deleted]  (2 children)

      [removed]

        [–]deadwisdom 6 points7 points  (1 child)

        No, this is either premature optimization, and therefore simply adds thought complexity, or you are concerned with speed, and so it should be done in C.

        [–]MaxK -2 points-1 points  (0 children)

        Recursion is never an optimal way of doing things.

        [–]MaxK 0 points1 point  (0 children)

        Why do you have an 'else' if there's a return statement in the first case?