web-dev-qa-db-fra.com

quand utiliser si vs Elif en python

Si j'ai une fonction avec plusieurs instructions conditionnelles où chaque branche est exécutée, la fonction renvoie les résultats. Devrais-je utiliser plusieurs instructions if, ou if/Elif/else? Par exemple, disons que j'ai une fonction:

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

Est-il préférable d'écrire:

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

Les deux ont le même résultat, mais l'un est-il plus efficace ou considéré comme plus idiomatique que l'autre?

Modifier:

Quelques personnes ont dit que, dans le premier exemple, les déclarations étaient toujours évaluées, ce qui ne semble pas être le cas pour moi.

par exemple si je lance le code:

l = [1,2,3]

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

test(5)

l sera toujours égal à [1,2,3]

14

Je vais développer mon commentaire pour une réponse.

Dans le cas où tous les cas reviennent, ceux-ci sont effectivement équivalents. Ce qui devient important en choisissant entre eux est alors ce qui est plus lisible.

Votre dernier exemple utilise la structure Elif pour indiquer explicitement que les cas sont mutuellement exclusifs, plutôt que de se fier implicitement aux retours. Cela rend cette information plus évidente, et par conséquent, le code plus facile à lire et moins sujet aux erreurs.

Disons, par exemple, que quelqu'un décide qu'il y a un autre cas:

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

Du coup, il y a un bug potentiel si l'utilisateur voulait que ce cas soit mutuellement exclusif (évidemment, cela n'a pas beaucoup de sens compte tenu de l'exemple, mais pourrait éventuellement dans un cas plus réaliste). Cette ambiguïté est supprimée si vous utilisez Elifs et que le comportement est rendu visible par la personne qui ajoute du code au niveau auquel elle est susceptible de s'intéresser lorsqu'elle l'ajoute.

Si je tombais sur votre premier exemple de code, je supposerais probablement que le choix d'utiliser ifs plutôt que elifs impliquait que les cas étaient non mutuellement exclusifs et que des modifications telles que la modification de la valeur de x pourraient être utilisées que ifs exécute (évidemment dans ce cas l'intention est évidente et s'exclut mutuellement, mais encore une fois, nous parlons de cas moins évidents - et la cohérence est bonne, donc même dans un exemple simple quand c'est évident, il vaut mieux s'en tenir à une voie ).

14
Gareth Latty

Regardez ceci pour comprendre la différence:

>>> 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

Le premier cas équivaut à deux noms if distincts avec des instructions else vides (ou imagine else: pass); dans le second cas, Elif fait partie de la première instruction if.

4
marco

Dans certains cas, Elif est requis pour une sémantique correcte. C'est le cas lorsque les conditions ne s'excluent pas mutuellement:

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

Dans certains cas, cela est efficace car l'interprète n'a pas besoin de vérifier toutes les conditions, ce qui est le cas dans votre exemple. Si x est négatif, alors pourquoi vérifiez-vous le cas positif? Elif dans ce cas rend également le code plus lisible, car il indique clairement qu'une seule branche sera exécutée.

3
perreal

En général (par exemple, votre exemple), vous utiliseriez toujours une échelle if..Elif pour indiquer explicitement que les conditions sont mutuellement exclusives. Cela évite les ambiguïtés, les bugs, etc.

La seule raison pour laquelle je peux penser que vous pourriez ne jamais utiliser Elif et plutôt utiliser if serait si les actions du corps de l'instruction if précédente (ou des précédentes instructions Elif) pouvaient avoir modifié la condition de manière à ne plus la rendre mutuellement exclusif. Ce n'est donc plus vraiment une échelle, mais des blocs if(..Elif..else) concaténés séparés. (Laissez une ligne vide entre les blocs séparés, pour plus de style et pour éviter que quelqu'un pense accidentellement qu'il aurait dû être Elif et le 'répare')

Voici un exemple artificiel, juste pour prouver le point:

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'

Vous pouvez voir qu'il est possible de remplir les deux conditions, si le premier if-block applique la réduction, alors nous exécutons également la seconde, qui imprime un message qui serait déroutant puisque notre total initial était> = 10.

Un Elif empêcherait ce scénario. Il peut toutefois exister d'autres scénarios dans lesquels nous souhaitons que le deuxième bloc soit exécuté, même pour ce scénario. 

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

Elif est un peu plus efficace et assez logique: avec ifs, le programme doit évaluer chaque expression logique à chaque fois. Dans Elifs cependant, ce n'est pas toujours le cas. Cependant, dans votre exemple, cette amélioration serait très très petite, probablement imperceptible, car évaluer x > 0 est l’une des opérations les moins chères.

Lorsque vous travaillez avec Elifs, il est également judicieux de réfléchir au meilleur ordre. Considérons cet exemple:

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

Ici, le programme devra évaluer l'expression laide à chaque fois! Cependant, si nous changeons l'ordre:

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

Maintenant, le programme va d'abord vérifier si x <0 (simple et économique) et si ce n'est pas le cas, il évaluera l'expression la plus compliquée (au fait, ce code n'a pas beaucoup de sens, c'est juste un exemple aléatoire)

Aussi, ce que perreal a dit.

0
Dunno

En ce qui concerne la partie edit de votre question quand vous avez dit: "Quelques personnes ont dit que, dans le premier exemple, les déclarations sont toujours évaluées, ce qui ne semble pas être le cas. pour moi"

Et puis vous avez fourni cet exemple:

l = [1,2,3]

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

test(5)

Oui, la liste l sera toujours égale à [1,2,3] dans ce cas, UNIQUEMENT parce que vous RETOURNEZ le résultat de l'exécution du bloc, car l'instruction return conduit à quitter la fonction, ce qui donnerait la même chose si vous utilisiez Elif avec le retour déclaration.

Maintenant, essayez d'utiliser l'instruction print au lieu de celle return, vous verrez que la deuxième instruction if s'exécutera correctement et que 4 sera effectivement ajouté à la liste l à l'aide de append.

Et bien .. maintenant que se passe-t-il si la première instruction if change la valeur de ce qui est évalué dans la seconde instruction if?

Et oui c'est une autre situation. Par exemple, supposons que vous avez une variable x et que vous avez utilisé l'instruction if pour évaluer un bloc de code qui a réellement modifié la valeur x. Maintenant, si vous utilisez une autre instruction if qui évalue la même variable x sera fausse depuis vous considérez que la valeur x est identique à sa valeur initiale, alors qu’elle a en fait été modifiée après l’exécution de la première if. Par conséquent, votre code sera faux.

Cela arrive assez souvent, et parfois vous voulez même que cela soit explicitement changé. Si c'est ainsi que vous voulez que votre code se comporte, alors oui, vous devriez utiliser plusieurs if qui font bien le travail. Sinon, respectez Elif.

Dans mon exemple, le premier bloc if est exécuté et modifie la valeur de x, ce qui conduit à ce que le 2nd if évalue un x différent (puisque sa valeur a été modifiée).

C'est là que Elif est utile pour empêcher que cela ne se produise, ce qui constitue le principal avantage de son utilisation. L'autre avantage secondaire bon de l'utilisation de Elif au lieu de plusieurs if consiste à éviter la confusion et un meilleur code lisibilité.

0
FouadDev