IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

(1 and [a] or [b])[0], quelle utilité ? Y'en a sûrement une..


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut (1 and [a] or [b])[0], quelle utilité ? Y'en a sûrement une..
    Salut tout le monde,

    en parcourant le forum, je suis tombé sur ce lien :
    http://python.developpez.com/cours/D...ion/and_or.php

    J'ai lu les astuces and-or, et les ai presque toutes captées, la seule dont je n'arrives pas voir l'utilité est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> a = ""
    >>> b = "second"
    >>> (1 and [a] or [b])[0]
    ''
    Puisque peu importe la valeur de a ou b, a sera toujours retourné, dès lors quel intérêt ?!?

    Je me dis que l'auteur n'a pas écrit ça pour rien, ça doit forcément servir à quelque chose...

    Donc si vous savez ou voyez l'utilité de cette astuce, pourriez-vous éclairer ma lanterne s'il-vous plait (par un exemple, si possible )

  2. #2
    Membre confirmé Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Par défaut
    T'as bien lu la suite?
    On peut penser que cette astuce apporte plus de complication que d’avantages. Après tout, on peut obtenir le même résultat avec une instruction if, alors pourquoi s’embarasser de tout ces problèmes ? Mais dans de nombreux cas, le choix se fait entre deux valeurs constantes et donc vous pouvez utiliser cette syntaxe plus simple sans vous inquiéter puisque vous savez que a vaudra toujours vrai. Et même si vous devez utiliser la version sûre plus complexe, il y a parfois de bonnes raisons de le faire, il y a des cas en Python où les instructions if ne sont pas autorisées, comme dans les fonctions lambda.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par zabibof Voir le message
    T'as bien lu la suite?
    Il ne te demande pas l'utilité du and-or qu'il dit avoir bien pigé, il te demande l'utilité du and-or dans ce cas précis où la condition est toujours vraie... (et moi aussi par la même occasion)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre confirmé Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Par défaut
    C'est donc moi qui n'a pas bien lu

    La véritable astuce cachée derrière l’astuce and-or, c’est de s’assurer que a ne vaut jamais faux. Une manière habituelle de le faire est de changer a en [a] et b en [b] et de prendre le premier élément de la liste retournée, qui sera soit a soit b.
    Bon, si j'ai bien compris, l'expression:
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (1 and [a] or [b])
    retourne la liste [a,b]
    et
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (0 and [a] or [b])
    retourne la liste [b,a]
    donc,
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (1 and [a] or [b])[0]
    et
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (0 and [a] or [b])[0]
    retournent respectivement a et b

    Bon, j'ai pas essayé mais ça doit être ça

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    En fait, cette forme est une simulation astucieuse du "if then else monoligne" qui existe dans certains langages (genre: (cond ? si-oui : si-non)) mais pas dans Python avant la version 2.5.

    Comment ça marche?

    on a:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (cond1 and cond2 or cond3)
    et cond2 et cond3 doivent être à True (donc jamais à 0).

    and et or ayant le même niveau de priorité seront exécutés de gauche à droite. Par ailleurs, si (cond1 and cond2) vaut True, le 'or' ne sera jamais exécuté.

    donc, si cond1 est vrai ainsi que cond2, renvoi de cond2. Sinon, le or est exécuté et cond3 est renvoyé.

    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    x=1
    y=2
    print (x<y and x or y)  # affiche 1
    print (x>y and x or y)  # affiche 2
    Mais dans cette forme, si x=0, ça ne marche plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print (x<y and x or y)  # affiche 2 au lieu de 0
    En effet, pour que ça marche, il ne faut pas que cond2 puisse être évalué à False (donc à 0). D'où l'astuce de passer par une liste qui sera toujours True (essayez: même [False] sera évalué à True!).

    Avec l'exemple ci-dessus x=0 et y=2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print (x<y and [x] or [y])[0]  # affiche 0
    print (x>y and [x] or [y])[0]  # affiche 2
    Et, effectivement, cette forme astucieuse peut être utilisée dans une fonction lambda alors qu'un if serait interdit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    est_pair = lambda x: ((x%2==0) and ['oui'] or ['non'])[0]
    print est_pair(10)  # affiche 'oui'
    print est_pair(11)  # affiche 'non'
    Avec Python 2.5, on a enfin un "if then else monoligne", même s'il n'est pas facile à trouver dans le manuel. Exemple, avec x=0 et y=2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print (x if x<y else y)  # affiche 0
    print (x if x>y else y)  # affiche 2
    Voir aussi la pep 308: http://www.python.org/dev/peps/pep-0308/

    Tyrtamos

  6. #6
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Ah.... tout de suite ça a plus de sens ! Merci

    Donc même si la forme est juste dans
    le fait de mettre un argument à valeur constante en premier rend le tout inutile, pour que ça garde toute son utilité, il faut que -ici- 1 soit remplacer par une variable ou une comparaison (ou toute autre chose susceptible de changer de valeur bool)...Je résume juste pour voir si bien compris...

    EDIT: Juste parceque j'aime bien taquiner en cherchant la petite bête
    Et, effectivement, cette forme astucieuse peut être utilisée dans une fonction lambda alors qu'un if serait interdit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    est_pair = lambda x: ((x%2==0) and ['oui'] or ['non'])[0]
    print est_pair(10)  # affiche 'oui'
    print est_pair(11)  # affiche 'non'
    Heu... ici cette forme n'est pas vraiment nécessaire...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    est_pair=lambda x: (x%2 is 0) and 'oui' or 'non'
    Cette dernière suffit ...

  7. #7
    Membre expérimenté
    Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2003
    Messages : 304
    Par défaut
    Citation Envoyé par N.tox Voir le message
    Salut tout le monde,

    en parcourant le forum, je suis tombé sur ce lien :
    http://python.developpez.com/cours/D...ion/and_or.php

    J'ai lu les astuces and-or, et les ai presque toutes captées, la seule dont je n'arrives pas voir l'utilité est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> a = ""
    >>> b = "second"
    >>> (1 and [a] or [b])[0]
    ''
    Puisque peu importe la valeur de a ou b, a sera toujours retourné, dès lors quel intérêt ?!?

    Je me dis que l'auteur n'a pas écrit ça pour rien, ça doit forcément servir à quelque chose...

    Donc si vous savez ou voyez l'utilité de cette astuce, pourriez-vous éclairer ma lanterne s'il-vous plait (par un exemple, si possible )
    Salut,

    condition and A or B veut dire : si condition est vrai retourner A, sinon retourner B. Voilà l'usage de cette syntaxe.

    Sauf que pour le cas précis que tu donnes, cela ne marche pas :

    Si tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    >>> a = ""
    >>> b = "b"
    >>> 0 and a or b
    'b'
    >>> 1 and a or b
    'b'
    Dans le premier cas

    On pense : si 0 est vrai (non) retourner a sinon retourner b. On s'attend à ce que le code retourner b est c'est bien ce qu'on a.

    Dans le deuxième cas on pense : si 1 est vrai (oui) alors retourner a sinon retourner b. On s'attend à ce que ça retourne a cette fois, mais non ! puisque a est vide, ça retourne b.

    Pour éviter que ça retourne b, on utilises donc l'astuce donné par l'auteur, pour que quelque soit la valeur de a (qu'elle s'évalue à False ou pas), on retourne à chaque fois sa valeur quand la condition est vrai.

    D'où
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> a = ""
    >>> b = "b"
    >>> (1 and [a] or [b])[0]
    ''
    retournera bien la valeur de a, comme on le voulait, et non celle de b.

    zabibof, les codes que tu as donné sont faux.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Le multitouch - quelle utilité?
    Par leyee dans le forum Débats sur le développement - Le Best Of
    Réponses: 13
    Dernier message: 14/05/2009, 18h18
  2. les interfaces; quelle utilité?
    Par noubigh dans le forum C#
    Réponses: 9
    Dernier message: 30/07/2008, 09h18
  3. Site Semi-dynamique quelle utilité ?
    Par ljp200250 dans le forum WebDev
    Réponses: 1
    Dernier message: 17/07/2008, 19h58
  4. (adodbconnection) quelles utilité?
    Par doogybreton dans le forum VBA Access
    Réponses: 5
    Dernier message: 20/01/2008, 12h24
  5. [DataWareHouse] Quelle utilité des clés de substitution ?
    Par alpachico dans le forum Alimentation
    Réponses: 3
    Dernier message: 23/03/2006, 13h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo