2009-04-20 8 views
14

Perlでは、オブジェクトを割り当てることができれば良いのですが、割り当て元の変数が 'undef'の場合は、フォールバックの値を指定するとよいでしょう。割り当てでフォールバック値を指定する最もPythonの方法は何ですか?

この後
my $x = undef; 
my $y = 2; 
my $a = $x || $y; 

$a == 2 

は、xの値がなし、またはフルに希望されない場合はPythonでこれを達成するための簡潔な方法があります...

if x is not None 
    a = x 
else 
    a = y 
:たとえば

...これを達成する最もPythonicな方法ですか?

EDIT:いくつかのコメント者から指摘されているように、私は実際には値が未定義であるとは言いませんでしたが、Perlでは 'undef'しかし、もともと言われたような問題は、これを明確にしていませんでした。

+2

「変数の割り当て元が未定義の場合」は誤っていることに注意してください。 "割り当てられている変数がfalseの場合"は真実に非常に近い。 – innaM

+1

Manniのコメントにフォローアップするには、Perl 5.10以降を使用できる場合は、定義済み演算子「//」を使用する方がよいでしょう。 (これはPythonでどのように行うのかとは関係ありません) –

答えて

26

2.5以降:

あなたはなしにのみフォールバックしたい場合:

a = x if x is not None else y 

あなたは空の文字列に戻っても落ちるしたい場合は、false0等:

a = x if x else y 

または

a = x or y 
未定義については

(定義されたことがないよう、別名バインドされていません):

try: 
    a = x 
except NameError: 
    a = y 

またはもう少しハック(私は実際にそれをお勧めしていないと思いますが、それは短いです):

a = vars().get('x',y) 
+0

私よりも良い方法... – Greg

+0

hm、xは結局定義されています。/ – SilentGhost

+0

@greg:これはあなたのものより良くはありませんが、それと等しく間違っています – SilentGhost

1

Pythonの三項演算があります:

a = x if x is not None else y 

2.5以上でご利用いただけます。

-1

それはあなたがこれを行うことができます関数の引数の場合:downvotersについては

def MyFunc(a=2): 
    print "a is %d"%a 

>>> MyFunc() 
...a is 2 
>>> MyFunc(5) 
...a is 5 

[編集]は、.. /他のビットは、ソリューションには不要な場合 - 結果だけを作るために追加明らかです。 ifステートメントを削除して、それが明確になったら削除しましたか?

+0

MyFuncにif elseを追加するために何が強制されたかわかりません。もしあなたがif、else、elseブロックをkillすると、全てが同じように動作します。 –

+0

もちろん、私は結果を説明しようとしていました! –

+0

あなたが修正してから+1に中和してください。 :) –

5

まずあなたが三元であなたの完全なオンを行うことができます。

a = y if x is None else x 

でも問題は解決しません。何がやりたいことは、より密接に実装されています。ステートメントは、xが0または負の場合には対応していません場合に頼るソリューションの

try: 
    a = x 
except: 
    a = y 
+0

申し訳ありませんが、これは実際に私が探していたものではありませんでしたが、私が実際に尋ねた質問に対する良い答えです! – maxaposteriori

+0

@Andy:あなたの質問に実際に答えていない理由を確認するために、受け入れられた回答に最も多く寄稿したコメントをお読みください。 – SilentGhost

+0

この解決方法は正しい方法と思われます。 try: a = x except: a = y – randlet

0

ほとんどを。あなたが先に時間の変数の名前を知っていた場合

>>> x = 0 
>>> y = 2 
>>> a = x or y 
>>> a 
2 
>>> 

あなたのようなので、ためになります:

if 'x' in dir(): 
    a = x 
except: 
    a =y 

そのソリューションは私に親切のずさんなようだが。私は最善の方法はそうのようなブロック以外試みを使用することであると信じて:これはニシキヘビのあるパターンではありませんので、

try: 
    a = x 
else: 
    a = y 
3

私は、これを行うには「神託」方法がないことはかなり確信しています。コントロールは、エレガントなコードで未定義の変数参照に到達するべきではありません。 pythonicという同様の考えがあります。最も明白:重要なのは何

def myRange(start, stop=None): 
    start, stop = (0, start) if stop is None else (start, stop) 
    ... 

stopがスコープで定義されていることですが、呼び出し側はそれを取っただけで、明示的にそれを渡すために持っていなかったことのデフォルト値、引数の意味を、変更するものでエフェクトは、第1引数が第2引数ではなくオプションであることを意味します。

このようなことは、try-catchブロックを使用せずに前提に従う可能性があります。この冗長なコードはに短縮することが可能

my $x = undef; 

:あなたのPerlの例と

a = locals().get('x', y) 
+0

+1 "これはpythonicなパターンではないので"と言ったとき合意した100% –

4

ただ、いくつかのつべこべ行いません

my $x; 

、次のコード、あなたはそれがない言います:

my $a = $x || $y; 

Th $ xがの場合、実際に$ yを$ aに割り当てます。です。誤った値には、undef、ゼロ、空の文字列などが含まれます。定義済みかについてのみテストするには、(5.10のように)次のことを行うことができます:書き換える

my $a = $x // $y; 
0

一つの方法...

if x is not None 
    a = x 
else 
    a = y 

を..です:例外を使用して、

​​

か(おそらくよりPython'yに応じてコードが何をしているのか - 正しい方法例外はおそらく使用して、エラーがあったので、それがNoneを返した場合):

try: 
    x = myfunction() 
except AnException: 
    x = "fallback" 

print x 

本当にあなたに何か問題が元のコードが存在しない、と述べているすべて:のいずれよりも

if x is not None 
    a = x 
else 
    a = y 

それは長いですが、私ははるかに容易に読み(とはるかにPython的)していることを見つけますフォローウィングワンライナー:

a = x if x is not None else y 
a = x or y 
関連する問題