2012-01-30 5 views
5

可能な重複のPythonの同等:
Python conditional assignment operatorのPerl/Rubyの|| =

このような簡単な質問に対して謝罪、しかし||=をグーグルでは非常に有用ではありません。)

RubyとPerlにある||=ステートメントと同等のものがPythonにありますか?例えば

foo = "hey" 
foo ||= "what" # assign foo if it's undefined 
# foo is still "hey" 

bar ||= "yeah" 
# bar is "yeah" 

また、このような何かのための一般的な用語は何ですか?条件付き割り当ては私の最初の推測でしたが、Wikipedia pageは私が心に留めていたものではありません。

+0

はい、重複しているようです。ありがとうございました! –

+2

'$ foo || =" what "'既に$ falseの場合は '$ foo'を再割り当てします。もちろん、 'undef'はfalseですが、そうでなければゼロとヌル文字列です。 '$ foo // =" what "' – Borodin

+0

のように、未定義の値だけを再割り当てするには、スラッシュを使用してください。perl 5.10では '//'とその拡張子 '// ='が追加されています。まだ5.8.xに固執しているなら、 '// ='を使うことはできません(できるだけアップグレードを真剣に考えてください)。 –

答えて

6

少しビットより多くの冗長が、私はあなたを理解している場合、最も簡単なあなたはまた、

bar = None 
bar = bar if bar else "yeah" 

三項演算子を使用することができます

foo = "hey" 
foo = foo or "what" 
#foo is still "hey" 

bar = None 
bar = bar or "yeah" 
#bar is "yeah" 

あるしかし、||=は以前にはなかった変数を割り当て定義された、苦情なしで?私は今まで知らなかった。

ローカルスコープでそれを行うには、この醜いアヒルの子は仕事ができる

bar = locals()['bar'] if 'bar' in locals() else 'yeah' 

編集:ただ、重複を見て、それがするのが面倒それらのため:)同様のソリューションをたくさん持っている

見て、彼らはまた、上のよりよいバリアントを含んで私の最後の1

foo = foo if 'foo' in locals() else 'hey' 

が、これは未定義の変数のために動作しません、唯一falsy値が置き換えられ、が発生します未定義されます。この次は、OTOH、誰かが例外:(

を使用し、ONLY未定義のために働き、常に@Borodinはもちろん、Perlの

foo = locals().get('foo','hey') 

//=のようなものであると言うのと同じ既存のfalsy値を、維持します

try: 
    v 
except NameError: 
    v = 'bla bla' 
+0

いいえ、 '|| ='は変数が 'false'ならば変数を再割り当てします。質問に対する私のコメントを参照してください。なぜあなたは苦情を期待していますか? – Borodin

+0

返事をいただきありがとうございます。最初はニュアンスの違いに気づきませんでした。 'bar = None'が動作するためには' bar = None'が必要です。それ以外の場合は 'NameError'がスローされます。同じ動作をするには 'locals()['bar']'スニペットが必要です。もう一度ありがとう:) –

+0

@borodin私はRubyistではない、私はシェフのような愚かなもののためにそれを使用した。私は、Rubyの 'undef'が偽であることを知らなかったことを意味しました。これはPythonではそうではないからです(未定義の参照は例外をスローします)。関係なく、あなたのコメントのおかげで、私は何かを学んだ:) –

1

ない名前がわから私が思い付くことが最高です:。

>>> a = 'foo' 
>>> a = 'a' in locals() and a or 'what' 
>>> a 
'foo' 
>>> b = 'b' in locals() and b or 'yeah' 
>>> b 
'yeah' 
2

あなたはめったにPythonで未定義の変数を持っていないだろう、とあなたが行うときには、通常、あなたがメートルを持っていることを意味間違いを犯す。しかし、好都合なことに、デフォルト(空のコンテナ、長さゼロの文字列、ゼロ、およびNone)として一般的に使用される値の種類のほとんどは、Pythonでは「偽」です。 Pythonでブール演算子の仕事:

name = name or "Guido" # if name is empty, set it to "Guido" 
numb = numb or 42  # if numb is zero, set it to 42 

この作品の理由は、最初の引数は短絡と呼ばれる「truthy」であり、いずれの場合も、実際の引数を返すのではなく、場合Pythonはorの評価を停止していることですその結果、単にTrueまたはFalseとなります。したがってnameが "Jim"の場合、"Jim"は長さがゼロでない文字列であり、 "真実"なので"Jim" or "Guido""Jim"と評価されます。

もちろん、あなたが扱っている値の型がわからない、あるいは「偽の」値が有効な値であることがわからないときは、うまく機能しません。辞書内のアイテムを扱う際にもう一つの一般的なイディオムが使用されている

name = raw_input("What is your name? ") or "Guido" 

:しかし、それはコンフィギュレーションファイルおよび欠損値が空の文字列を返しますraw_input()のようなもので、かなりうまく動作します。辞書クラスのget()メソッドでは、変数が辞書にない場合に使用されるデフォルト値を指定できます。

name = values.get("name", "Guido") 

**kwargs規約を使用して関数にキーワード引数が渡されたときに使用できます。

name = locals().get("name", "Guido") 

しかし、私が言ったように、あなたはめったにありませんでしょう、:globals()locals()機能が辞書としてスコープ現在、それぞれ、すべてのグローバルまたはローカル変数を返すようあなたはも、変数でそれを使用することができますPythonでは実際には未定義の変数です。 Webフレームワークのような場合は、クエリ文字列の引数を辞書に渡して、辞書の.get()メソッドを使用できます。

名前が実際には存在しない(たとえば、設定ファイルがPython構文であり、それを解析するのではなくPythonモジュールとしてインポートし、ユーザーが省略できるようにする

import config 
name = getattr(config, "name", "Guido") # rather than just name.config 

それとも、それはNameErrorを投げると、それをキャッチしてみましょう:いくつかの値...または均等奇抜な何か)あなたは、デフォルト値を受け入れている(辞書の.get()など)、getattr()を使用することができます。

関連する問題