2

私はPythonのリスト内包表記を少しいじっていましたが、このワンライナーを作成して、2つの3桁の数字の積として作成される最大偶数を計算しました。

max([ i*j for i in range(100,1000) for i in range(100,1000) if i*j%2== 0 ]) 

問題は次のとおりです。一時的な名前を割り当てて使用するなど、i*j の値の再計算を回避する方法はありますか?

私を悩ませているのは、i*j2回の値を計算していて、if関数がもう1つ必要な場合は、もう1つ必要だということです。それを修正する方法はありますか?

4

3 に答える 3

3

が高価な場合i*jは、ジェネレーター関数を使用します。

def values():
    for i in range(100, 1000):
        for j in range(100, 1000):
            ij = i * j
            if ij % 2 == 0:
                yield ij

max(values())

ここでジェネレータ式をネストする誘惑に抵抗してください。はい、実行できますが、コードを解読できないようにするだけです。

于 2013-03-20T12:32:34.683 に答える
0

インタプリタがあなたのコードをどのように処理するかはわかりません。

しかし、あなたは使うことができます:

max((u for u in (i*j for i in range(100,1000) for j in range(100,1000)) if u%2== 0))

そしてこの場合、リスト[]を使用する代わりにジェネレーター()を使用する方が良いと思います。すべてのデータを必要とせず、最大のデータだけが必要だからです。

于 2013-03-20T12:37:53.520 に答える
0

一般的に言えば、次のように言うのは Python の哲学の範囲内です。中間結果を再利用したい場合は、名前を付けてください。慣用 _的に、一時的な名前を提案するために使用されます。また、リスト内包表記またはジェネレータ式が 2 行以上にまたがる場合は、とにかく明示的な for ループで書き直すのがおそらく最善です。

とは言うものの、Python の関数機能を (誤って) 使用して、中間名なしでコードを作成する可能性があります。ほぼ、つまり: を使用functools.partialして左端およびキーワード以外の引数を固定することはできないため、 を使用するmod2代わりに、関数を自分で作成する必要がありpartialます。

from itertools import iterfalse, product, starmap
from operator import mod, mul
mod2 = lambda x: mod(x, 2) # this would be nicer with functools.partial
max(filterfalse(mod2, starmap(mul, product(range(100, 1000), repeat=2))))

ただし、上記のコードがあなたの質問に答えると信じていますが、この解決策は直感的に理解できるとは思いません。中間結果に名前を付けてください。

于 2013-09-02T11:00:25.140 に答える