web-dev-qa-db-fra.com

Manière plus courte et plus pythonique d'écrire une instruction if

J'ai ceci

bc = 'off'

if c.page == 'blog':
    bc = 'on'

print bc

Existe-t-il une manière plus pythonique (et/ou plus courte) d'écrire ceci en python?

44
32423hjh32423

Le plus court devrait être:

bc = 'on' if c.page=='blog' else 'off'

En général, cela peut sembler un peu déroutant, vous ne devez donc l'utiliser que lorsque la signification est claire. Ne l'utilisez pas pour les grosses clauses booléennes, car il commence à paraître très laid.

95
freiksenet

C'est:

  1. certainement plus court
  2. sans doute Pythonic (pré-Python 2.5, qui a introduit le controversé X if Z else Y syntaxe)
  3. douteusement lisible. Avec ces mises en garde à l'esprit, voici:

    bc = ("off","on")[c.page=="blog"]
    

EDIT: Selon la demande, le formulaire généralisé est:

   result = (on_false, on_true)[condition]

Explication: condition peut être tout ce qui correspond à un booléen. Il est ensuite traité comme un entier car il est utilisé pour indexer le Tuple: False == 0, True == 1, qui sélectionne ensuite le bon élément dans le tuple.

65
Arkady

Eh bien, ne pas être un gars python s'il vous plaît prendre cela avec un énorme grain de sel, mais avoir écrit (et, avec plus de difficulté, lire) beaucoup de code intelligent au fil des ans, je me retrouve maintenant avec une forte préférence pour le code lisible. J'ai eu l'essentiel de ce que faisait votre code d'origine même si je ne suis personne en tant que gars Python. Pour être bien sûr, vous pourriez le cacher et peut-être impressionner un Python wonk ou deux, mais pourquoi?

33
John Lockwood

Ou vous pouvez utiliser une instruction if en ligne:

>>> cpage = 'blog'
>>> bc = 'on' if cpage == 'blog' else 'off'
>>> bc
'on'
>>> cpage = 'asdf'
>>> bc = 'on' if cpage == 'blog' else 'off'
>>> bc
'off'

Il y a un peu de synthèse sur cette fonctionnalité sur ce blog , et le PEP pertinent est PEP308 . L'instruction if en ligne a été introduite dans Python 2.5.

Celui-ci peut être un peu moins Pythonic, mais vous pouvez utiliser et/ou de cette façon:

>>> cpage = 'asdf'
>>> bc = (cpage == 'blog') and 'on' or 'off'
>>> bc
'off'
>>> cpage = 'blog'
>>> bc = (cpage == 'blog') and 'on' or 'off'
>>> bc
'on'

Celui-ci est utilisé plus souvent dans les instructions lambda que sur une ligne seule, mais le formulaire

 A and B or C

est similaire à

   if A:
       return B
   else:
       return C

J'allais écrire une explication un peu plus longue, mais ils l'ont mieux couverte à Dive into Python . Ils ont également noté quelques mises en garde que vous devez probablement savoir.

13
Mark Rushakoff

Une autre possibilité consiste à utiliser un dict si vous pouvez calculer les valeurs en dehors de la fonction qui y accède (c'est-à-dire que les valeurs sont statiques, ce qui résout également le problème d'évaluation dans les commentaires de la réponse de scrible).

want_bc = {True: "on", False: "off"}
# ...
bc = want_bc[c.page == "blog"]

Je préfère cela et/ou les solutions d'indexation de Tuple sous la rubrique générale de préférer le calcul aux tests.

5
user135331

Vous pouvez utiliser,

a = b if c else d 

mais si vous utilisez une version python antérieure à 2.5,

bc = c.page == "blog" and "on" or "off"

peut aussi faire l'affaire.

2
M. Utku ALTINKAYA