5

私はプロジェクトオイラーの問題14に取り組んでおり、最初の試みとして、この強引な解決策を打ち出しました。

def collatz(n, memo={1: [1]}):
    if n not in memo:
        memo[n] = [n] + collatz(3 * n + 1 if n % 2 else n // 2)
    return memo[n]

def p014():
    return max(xrange(1, 10**6), key=lambda n: len(collatz(n)))

私の質問はそのラムダについてです、私は通常それらを使用するのを嫌がります、しかし私はこの場合それを避けるためのエレガントな方法を知りません。2つの呼び出し可能オブジェクトをチェーンするための何か、functoolsまたは私が見逃している他のきちんとした代替手段はありますか?

4

2 に答える 2

6

関数があれば素敵でしょうcompose-おそらくfunctools残念ながら、存在しないし、存在するとは思わない。レイモンド・ヘッティンガーの言葉によれば、

これは以前に他のフォーラムで議論され、拒否されました。問題の1つは、通常の数学的順序が直感的ではなく、自己文書化されていないことです。つまり、またはcompose(f,g) と同じですか?また、独自の合成関数を作成したり、直接合成を実行したりするのは、すでに簡単です 。f(g(x))g(f(x))h = lambda x: f(g(x))

呼び出し可能なクラスとしての2つの簡単な実装を次に示します。compose

# Scott Daniels, http://code.activestate.com/recipes/52902-function-composition/
# Lightly edited for style.
class Compose(object):
    '''Compose functions. compose(f,g,x...)(y...) = f(g(y...),x...))'''
    def __init__(self, f, g, *args, **kwargs):
        self.f = f
        self.g = g
        self.pending = args[:]
        self.kwargs = kwargs.copy()

    def __call__(self, *args, **kwargs):
        return self.f(self.g(*args, **kwargs), *self.pending, **self.kwargs)


class Starcompose:
    '''Compose functions. Starcompose(f,g,x...)(y...) = f(*g(y...),x...))'''
    TupleType = type(())

    def __init__(self, f, g, *args, **kwargs):
        self.f = f
        self.g = g
        self.pending = args[:]
        self.kwargs = kwargs.copy()

    def __call__(self, *args, **kwargs):
        mid = self.g(*args, **kwargs)
        if isinstance(mid, self.TupleType):
            return self.f(*(mid + self.pending), **self.kwargs)
        return self.f(mid, *self.pending, **self.kwargs)

また、少し前に私のfunctionalこの非常に単純な機能に影響を与えたパッケージを参照してください。compose_many

def compose(f1, f2):
    def composition(*args, **kwargs):
        return f1(f2(*args, **kwargs))
    return composition

def compose_many(*funcs):
    return reduce(compose, funcs)
于 2012-11-04T14:27:29.080 に答える
2

これをジェネレーターとして書く方がよりPython的かもしれません:

def p014():
    length, n = max(
        (len(collatz(n)), n)
        for n in xrange(1, 10**6)
    )
    return n
于 2012-11-04T14:43:20.237 に答える