web-dev-qa-db-ja.com

pythonでif vs Elifを使用する場合

すべての分岐が実行される複数の条件ステートメントを持つ関数がある場合、関数から戻ります。複数のifステートメント、またはif/Elif/elseを使用する必要がありますか?たとえば、次の関数があるとします。

def example(x):
    if x > 0:
        return 'positive'
    if x < 0:
        return 'negative'
    return 'zero'

書く方が良いですか:

def example(x):
    if x > 0:
        return 'positive'
    Elif x < 0:
        return 'negative'
    else:
        return 'zero'

どちらも同じ結果になりますが、一方がもう一方よりも効率的であるか、またはより慣用的であると考えられていますか?

編集:

最初の例では、ifステートメントは常に評価されますが、私にはそうではないようです。

たとえば、コードを実行すると:

l = [1,2,3]

def test(a):
    if a > 0:
        return a
    if a > 2:
        l.append(4)

test(5)

lは[1,2,3]のままです。

18

コメントを回答に拡張します。

すべてのケースが戻る場合、これらは実際に同等です。それらの中から選択する際に重要になるのは、それから、より読みやすいものです。

後者の例では、Elif構造体を使用して、ケースが暗黙的に戻り値であるという事実に依存するのではなく、ケースが相互に排他的であることを明示的に述べています。これにより、その情報がより明確になり、コードが読みやすくなり、エラーが発生しにくくなります。

たとえば、別のケースがあると誰かが判断したとします。

def example(x):
    if x > 0:
        return 'positive'
    if x == -15:
        print("special case!")
    if x < 0:
        return 'negative'
    return 'zero'

突然、ユーザーがそのケースを相互に排他的にすることを意図した場合、潜在的なバグがあります(明らかに、これは例ではあまり意味がありませんが、より現実的なケースでは可能性があります)。 Elifsが使用され、コードを追加するときに見ている可能性が高いレベルでコードを追加する人に動作が表示される場合、このあいまいさが取り除かれます。

最初のコード例に出くわした場合、ifではなくelifssを使用するという選択は、ケースがnotとは相互に排他的であることを暗示していると思います。したがって、xの値を変更するなどの方法を使用して、どのifsを実行するかを変更できます(明らかにこの場合、意図は明白であり、相互に排他的ですが、ここでも、あまり明確でないケースについて話しています-一貫性は良いので、簡単な例でも明らかな場合は、一方向に固執するのが最善です)。

17
Gareth Latty

違いを理解するためにこれをチェックしてください:

>>> a = 2
>>> if a > 1: a = a+1
...
>>> if a > 2: a = a+1
...
>>> a
4

versus

>>> a = 2
>>> if a > 1: a = a+1
... Elif a > 2: a = a+1
...
>>> a
3

最初のケースは、空のifステートメントを含む2つの異なるelseに相当します(またはelse: pass); 2番目のケースでは、Elifは最初のifステートメントの一部です。

6
marco

場合によっては、正しいセマンティクスのためにElifが必要です。これは、条件が相互に排他的でない場合です。

if x == 0:   result = 0
Elif y == 0: result = None
else:        result = x / y

インタプリタがすべての条件をチェックする必要がないため、場合によっては効率的です。これは、例の場合です。 xが負の場合、なぜ正のケースをチェックするのですか?この場合のElifは、単一の分岐のみが実行されることを明確に示すため、コードを読みやすくします。

3
perreal

一般に(例:例)、常に_if..Elif_ラダーを使用して、条件が相互に排他的であることを明示的に示します。あいまいさ、バグなどを防ぎます。

Elifを使用せず、代わりにifを使用する可能性があると考えることができる唯一の理由は、前のifステートメント(または以前のElifステートメント)は、相互に排他的ではなくなる可能性があるように条件を変更した可能性があります。つまり、実際にははしごではなく、連結されたif(..Elif..else)ブロックを分離するだけです。 (スタイルを整えて、誰かが誤ってそれをElifであると考えて '修正'する必要があると思わないようにするために、個別のブロックの間に空白行を残します)

ここで、要点を証明するための、不自然な例を示します。

_if total_cost>=10:
    if give_shopper_a_random_discount():
        print 'You have won a discount'
        total_cost -= discount
    candidate_prime = True

if total_cost<10:
    print 'Spend more than $10 to enter our draw for a random discount'
_

最初のifブロックが割引を適用する場合、両方の条件に達する可能性があることがわかります。そのため、2番目のifブロックも実行します。これは、元の合計が10以上だったため混乱するメッセージを出力します。

ここでElifを使用すると、このシナリオを防ぐことができます。しかし、そのシナリオであっても、2番目のブロックを実行したい他のシナリオが存在する可能性があります。

_if total_cost<10:
    <some other action we should always take regardless of original undiscounted total_cost>
_
2
smci

Elifの方が少し効率的で、非常に論理的です。ifsを使用すると、プログラムは毎回各論理式を評価する必要があります。 Elifsでは、常にそうであるとは限りません。ただし、あなたの例では、x > 0の評価が最も安価な操作の1つであるため、この改善は非常に小さく、おそらく気づかないでしょう。

Elifsを使用する場合は、最適な順序を考えることもお勧めします。この例を考えてみましょう:

if (x-3)**3+(x+1)**2-6*x+4 > 0:
    #do something 1
Elif x < 0:
    #do something 2

ここでは、プログラムは毎回醜い表現を評価する必要があります!ただし、順序を変更した場合:

if x < 0:
   #do something 2
Elif (x-3)**3+(x+1)**2-6*x+4 > 0:
   #do something 1

プログラムは最初にx <0(安価で単純)かどうかをチェックし、そうでない場合にのみ、より複雑な式を評価します(ところで、このコードはあまり意味がなく、単なるランダムな例です)。

また、パーリアルが言ったこと。

0
Dunno

あなたが言ったときのあなたの質問のeditの部分について:「最初の例では、ifステートメントは常に評価されるので、私には当てはまらないようです。 」

そして、あなたはこの例を提供しました:

l = [1,2,3]

def test(a):
    if a > 0:
        return a
    if a > 2:
        l.append(4)

test(5)

はい、確かにリストl[1,2,3]この場合、returnステートメントが関数の終了につながり、Elifを使用した場合と同じ結果になるため、ブロックを実行した結果を返すだけです。 returnステートメントを使用します。

次に、printの代わりにreturnステートメントを使用してみます。2番目のifステートメントが正常に実行され、その4は実際にlを使用してリストappendに追加されます。

さて..最初のifstatementが2番目のifステートメントで評価されているものの値を変更するとどうなりますか?

そして、はい、それは別の状況です。たとえば、変数xがあり、ifステートメントを使用して、実際にx値を変更したコードのブロックを評価したとします。ここで、同じ変数を評価する別のifステートメントを使用する場合、xの値を最初の値と同じと見なしているため、xは間違っています。実際、最初のifが実行された後に変更されました。したがって、コードは正しくありません。

これはかなり頻繁に発生し、場合によっては明示的に変更することもできます。それがあなたのコードが振る舞うことを望むなら、そうです、あなたはうまくいく複数のifを使うべきです。それ以外の場合は、Elifを使用します。

私の例では、1番目のifブロックが実行され、xの値が変更されます。これにより、2番目のifは別のxを評価します(その値は変更されました)。

このような場合にElifが役立つのは、このようなことが起こらないようにするためです。これが、この機能を使用する主な利点です。他のsecondary複数のElifではなくifを使用することの良い利点は、混乱を防ぎ、コードを読みやすくすることです。

0