34
def isBig(x):
   if x > 4: 
       return 'apple'
   else: 
       return 'orange'

これは機能します:

if isBig(y): return isBig(y)

これは動作しません:

if fruit = isBig(y): return fruit

なぜ2番目は機能しないのですか!? 1ライナーが欲しい。ただし、最初のものは関数を 2 回呼び出します。

関数を2回呼び出さずに1ライナーにする方法は?

4

7 に答える 7

18

他の誰かが私の古い「割り当てと設定」クックブックレシピをすでに指摘しているのがわかります。これは、最も単純なバージョンでは次のように要約されます。

class Holder(object):
   def set(self, value):
     self.value = value
     return value
   def get(self):
     return self.value

h = Holder()

...

if h.set(isBig(y)): return h.get()

ifただし、これは主に、Pythonと、またはで割り当てが直接サポートされている言語との間の音訳を容易にすることを目的としていますwhile。このようなチェックアンドリターンをカスケードで「数百」行う場合は、まったく異なることを行う方がはるかに優れています。

hundreds = isBig, isSmall, isJuicy, isBlah, ...

for predicate in hundreds:
  result = predicate(y)
  if result: return result

またはのようなもの

return next(x for x in (f(y) for f in hundreds) if x)

述語が満たされない場合にStopIteration例外を取得しても問題がない場合、または

return next((x for x in (f(y) for f in hundreds) if x)), None)

ifNoneは、述語が満たされない場合の適切な戻り値などです。

ほとんどの場合、トリック/非イディオムを使用する(または希望する)Holderことは、別のよりPythonicなアプローチを探すことを示唆する「デザインの匂い」です-Holder正当化される1つのケースは、まさに私がそれを設計しました。つまり、PythonコードとPython以外のコードとの密接な対応を維持したい場合(Pythonで参照アルゴリズムを変換し、よりPythonの形式にリファクタリングする前に最初に機能させたい場合、またはPythonをプロトタイプとして書き直し、効果的に機能すると、C ++、C#、Javaなどに変換されます)。

于 2009-10-11T17:31:16.687 に答える
8

fruit = isBig(y)Python では、代入 ( ) は式ではなくステートメントであるため、ワンライナーは機能しません。ifC、C++、Perl、およびその他の無数の言語では、これは式であり、好きなようにや などに入れることができますがwhile、Python ではできません。Python の作成者は、これがあまりにも簡単に誤用 (または悪用) されると考えていたからです。 )「賢い」コードを書く(あなたがしようとしているように)。

また、あなたの例はかなりばかげています。false である唯一の文字列は空の文字列 ( ) であるため、isBig()常に評価されるため、この場合、ステートメントは役に立ちません。それはあなたがやろうとしていることを単純化したにすぎないと思います。これを行うだけです:true""if

tmp = isBig(y)
if tmp: return tmp

それは本当にもっと悪いですか?

于 2009-10-11T08:03:25.283 に答える
2

PHP (または C) でコーディングする場合は、PHP でコーディングします。そのメソッドを別の言語に強制しようとしないでください。

(私の意見では) Python の背後にある基本原則の 1 つは、その読みやすさです。以下を使用する必要があります。

fruit = isBig(y)
if fruit: return fruit

また、あなたの の使用isXXX()は非常に奇妙です。通常、ブール値を返すために使用されます。特にこの場合、IFステートメントで使用しています。

于 2009-10-11T08:03:19.947 に答える
0

問題は、代入演算がブール値を持つと評価できないことです。このifステートメントは、ブール値を評価できることに依存しています。例えば、

>>> fruit = 'apple'
>>> bool(fruit = 'apple')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/Users/jem/<ipython console> in <module>()

TypeError: 'fruit' is an invalid keyword argument for this function
>>> bool('a')
True
于 2009-10-11T08:02:37.577 に答える
-8
print "apple" if x > 4 else "orange"
于 2013-10-30T16:22:20.393 に答える