Question

Je souhaite écrire une fonction en Python qui renvoie différentes valeurs fixes en fonction de la valeur d'un index d'entrée.

Dans d'autres langues, j'utiliserais un switch ou case déclaration, mais Python ne semble pas avoir de switch déclaration.Quelles sont les solutions Python recommandées dans ce scénario ?

Était-ce utile?

La solution

Vous pouvez utiliser un dictionnaire :

def f(x):
    return {
        'a': 1,
        'b': 2,
    }[x]

Autres conseils

Si vous souhaitez des valeurs par défaut, vous pouvez utiliser le dictionnaire get(key[, default]) méthode:

def f(x):
    return {
        'a': 1,
        'b': 2
    }.get(x, 9)    # 9 is default if x not found

J'ai toujours aimé faire ça de cette façon

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)

D'ici

En plus des méthodes de dictionnaire (que j'aime beaucoup, BTW), vous pouvez également utiliser if-elif-else pour obtenir la fonctionnalité switch/case/default :

if x == 'a':
    # Do the thing
elif x == 'b':
    # Do the other thing
if x in 'bc':
    # Fall-through by not using elif, but now the default case includes case 'a'!
elif x in 'xyz':
    # Do yet another thing
else:
    # Do the default

Bien sûr, ce n'est pas identique au switch/case - vous ne pouvez pas échouer aussi facilement que de quitter la pause ;déclaration, mais vous pouvez passer un test plus compliqué.Son formatage est plus agréable qu'une série de if imbriqués, même si fonctionnellement c'est ce dont il est le plus proche.

Ma recette Python préférée pour switch/case est :

choices = {'a': 1, 'b': 2}
result = choices.get(key, 'default')

Court et simple pour des scénarios simples.

Comparez avec plus de 11 lignes de code C :

// C Language version of a simple 'switch/case'.
switch( key ) 
{
    case 'a' :
        result = 1;
        break;
    case 'b' :
        result = 2;
        break;
    default :
        result = -1;
}

Vous pouvez même attribuer plusieurs variables en utilisant des tuples :

choices = {'a': (1, 2, 3), 'b': (4, 5, 6)}
(result1, result2, result3) = choices.get(key, ('default1', 'default2', 'default3'))
class switch(object):
    value = None
    def __new__(class_, value):
        class_.value = value
        return True

def case(*args):
    return any((arg == switch.value for arg in args))

Usage:

while switch(n):
    if case(0):
        print "You typed zero."
        break
    if case(1, 4, 9):
        print "n is a perfect square."
        break
    if case(2):
        print "n is an even number."
    if case(2, 3, 5, 7):
        print "n is a prime number."
        break
    if case(6, 8):
        print "n is an even number."
        break
    print "Only single-digit numbers are allowed."
    break

Essais :

n = 2
#Result:
#n is an even number.
#n is a prime number.
n = 11
#Result:
#Only single-digit numbers are allowed.

Il y a un modèle que j'ai appris du code Twisted Python.

class SMTP:
    def lookupMethod(self, command):
        return getattr(self, 'do_' + command.upper(), None)
    def do_HELO(self, rest):
        return 'Howdy ' + rest
    def do_QUIT(self, rest):
        return 'Bye'

SMTP().lookupMethod('HELO')('foo.bar.com') # => 'Howdy foo.bar.com'
SMTP().lookupMethod('QUIT')('') # => 'Bye'

Vous pouvez l'utiliser à tout moment lorsque vous avez besoin d'envoyer un jeton et d'exécuter un morceau de code étendu.Dans une machine à états, vous auriez state_ méthodes et expédition sur self.state.Ce commutateur peut être proprement étendu en héritant de la classe de base et en définissant la vôtre. do_ méthodes.Souvent, tu n'auras même pas do_ méthodes dans la classe de base.

Modifier:comment est-ce utilisé exactement

En cas de SMTP, vous recevrez HELO du fil.Le code correspondant (de twisted/mail/smtp.py, modifié pour notre cas) ressemble à ceci

class SMTP:
    # ...

    def do_UNKNOWN(self, rest):
        raise NotImplementedError, 'received unknown command'

    def state_COMMAND(self, line):
        line = line.strip()
        parts = line.split(None, 1)
        if parts:
            method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
            if len(parts) == 2:
                return method(parts[1])
            else:
                return method('')
        else:
            raise SyntaxError, 'bad syntax'

SMTP().state_COMMAND('   HELO   foo.bar.com  ') # => Howdy foo.bar.com

Vous recevrez ' HELO foo.bar.com ' (ou vous pourriez obtenir 'QUIT' ou 'RCPT TO: foo').Ceci est symbolisé en parts comme ['HELO', 'foo.bar.com'].Le nom réel de la recherche de méthode provient de parts[0].

(La méthode originale est aussi appelée state_COMMAND, car il utilise le même modèle pour implémenter une machine à états, c'est-à-dire getattr(self, 'state_' + self.mode))

Mon préféré est vraiment sympa recette.Vous l'aimerez vraiment.C'est la version la plus proche que j'ai vue des véritables instructions de switch case, en particulier en termes de fonctionnalités.

class switch(object):
    def __init__(self, value):
        self.value = value
        self.fall = False

    def __iter__(self):
        """Return the match method once, then stop"""
        yield self.match
        raise StopIteration

    def match(self, *args):
        """Indicate whether or not to enter a case suite"""
        if self.fall or not args:
            return True
        elif self.value in args: # changed for v1.5, see below
            self.fall = True
            return True
        else:
            return False

Voici un exemple :

# The following example is pretty much the exact use-case of a dictionary,
# but is included for its simplicity. Note that you can include statements
# in each suite.
v = 'ten'
for case in switch(v):
    if case('one'):
        print 1
        break
    if case('two'):
        print 2
        break
    if case('ten'):
        print 10
        break
    if case('eleven'):
        print 11
        break
    if case(): # default, could also just omit condition or 'if True'
        print "something else!"
        # No need to break here, it'll stop anyway

# break is used here to look as much like the real thing as possible, but
# elif is generally just as good and more concise.

# Empty suites are considered syntax errors, so intentional fall-throughs
# should contain 'pass'
c = 'z'
for case in switch(c):
    if case('a'): pass # only necessary if the rest of the suite is empty
    if case('b'): pass
    # ...
    if case('y'): pass
    if case('z'):
        print "c is lowercase!"
        break
    if case('A'): pass
    # ...
    if case('Z'):
        print "c is uppercase!"
        break
    if case(): # default
        print "I dunno what c was!"

# As suggested by Pierre Quentel, you can even expand upon the
# functionality of the classic 'case' statement by matching multiple
# cases in a single shot. This greatly benefits operations such as the
# uppercase/lowercase example above:
import string
c = 'A'
for case in switch(c):
    if case(*string.lowercase): # note the * for unpacking as arguments
        print "c is lowercase!"
        break
    if case(*string.uppercase):
        print "c is uppercase!"
        break
    if case('!', '?', '.'): # normal argument passing style also applies
        print "c is a sentence terminator!"
        break
    if case(): # default
        print "I dunno what c was!"
class Switch:
    def __init__(self, value):
        self.value = value

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        return False # Allows a traceback to occur

    def __call__(self, *values):
        return self.value in values


from datetime import datetime

with Switch(datetime.today().weekday()) as case:
    if case(0):
        # Basic usage of switch
        print("I hate mondays so much.")
        # Note there is no break needed here
    elif case(1,2):
        # This switch also supports multiple conditions (in one line)
        print("When is the weekend going to be here?")
    elif case(3,4):
        print("The weekend is near.")
    else:
        # Default would occur here
        print("Let's go have fun!") # Didn't use case for example purposes

Disons que vous ne souhaitez pas simplement renvoyer une valeur, mais que vous souhaitez utiliser des méthodes qui modifient quelque chose sur un objet.Utiliser l’approche indiquée ici serait :

result = {
  'a': obj.increment(x),
  'b': obj.decrement(x)
}.get(value, obj.default(x))

Ce qui se passe ici, c'est que Python évalue toutes les méthodes du dictionnaire.Ainsi, même si votre valeur est « a », l'objet sera incrémenté et décrémenté de x.

Solution:

func, args = {
  'a' : (obj.increment, (x,)),
  'b' : (obj.decrement, (x,)),
}.get(value, (obj.default, (x,)))

result = func(*args)

Vous obtenez donc une liste contenant une fonction et ses arguments.De cette façon, seuls le pointeur de fonction et la liste d'arguments sont renvoyés, pas évalué.'result' évalue ensuite l'appel de fonction renvoyé.

Je vais juste déposer mes deux cents ici.La raison pour laquelle il n'y a pas d'instruction case/switch en Python est que Python suit le principe selon lequel « il n'y a qu'une seule bonne façon de faire quelque chose ».Vous pouvez donc évidemment proposer différentes manières de recréer la fonctionnalité switch/case, mais la manière pythonique d'y parvenir est la construction if/elif.c'est à dire

if something:
    return "first thing"
elif somethingelse:
    return "second thing"
elif yetanotherthing:
    return "third thing"
else:
    return "default thing"

Je pensais juste que PEP 8 méritait un clin d'œil ici.L'une des belles choses de Python est sa simplicité et son élégance.Cela découle en grande partie des principes énoncés dans le PEP 8, notamment « Il n'y a qu'une seule bonne façon de faire quelque chose ».

développer l'idée "dict as switch".si vous souhaitez utiliser une valeur par défaut pour votre commutateur :

def f(x):
    try:
        return {
            'a': 1,
            'b': 2,
        }[x]
    except KeyError:
        return 'default'

Si vous avez un bloc de cas compliqué, vous pouvez envisager d'utiliser une table de recherche de dictionnaire de fonctions...

Si vous ne l'avez pas encore fait, c'est une bonne idée d'accéder à votre débogueur et de voir exactement comment le dictionnaire recherche chaque fonction.

NOTE:Faire pas utilisez "()" dans la recherche de cas/dictionnaire ou il appellera chacune de vos fonctions lors de la création du bloc dictionnaire/cas.N'oubliez pas cela car vous ne souhaitez appeler chaque fonction qu'une seule fois à l'aide d'une recherche de style de hachage.

def first_case():
    print "first"

def second_case():
    print "second"

def third_case():
    print "third"

mycase = {
'first': first_case, #do not use ()
'second': second_case, #do not use ()
'third': third_case #do not use ()
}
myfunc = mycase['first']
myfunc()

Si vous recherchez une instruction supplémentaire, comme "switch", j'ai construit un module python qui étend Python.C'est appelé ESPION sous le nom de « Structure améliorée pour Python » et il est disponible pour Python 2.x et Python 3.x.

Par exemple, dans ce cas, une instruction switch pourrait être exécutée par le code suivant :

macro switch(arg1):
    while True:
        cont=False
        val=%arg1%
        socket case(arg2):
            if val==%arg2% or cont:
                cont=True
                socket
        socket else:
            socket
        break

que l'on peut utiliser comme ceci :

a=3
switch(a):
    case(0):
        print("Zero")
    case(1):
        print("Smaller than 2"):
        break
    else:
        print ("greater than 1")

alors traduisez-le en Python comme suit :

a=3
while True:
    cont=False
    if a==0 or cont:
        cont=True
        print ("Zero")
    if a==1 or cont:
        cont=True
        print ("Smaller than 2")
        break
    print ("greater than 1")
    break

Je n'ai trouvé la réponse simple que je cherchais nulle part dans la recherche Google.Mais je l'ai quand même compris.C'est vraiment très simple.J'ai décidé de le publier, et peut-être d'éviter quelques égratignures de moins sur la tête de quelqu'un d'autre.La clé est simplement "in" et les tuples.Voici le comportement de l'instruction switch avec fall-through, y compris RANDOM fall-through.

l = ['Dog', 'Cat', 'Bird', 'Bigfoot',
     'Dragonfly', 'Snake', 'Bat', 'Loch Ness Monster']

for x in l:
    if x in ('Dog', 'Cat'):
        x += " has four legs"
    elif x in ('Bat', 'Bird', 'Dragonfly'):
        x += " has wings."
    elif x in ('Snake',):
        x += " has a forked tongue."
    else:
        x += " is a big mystery by default."
    print(x)

print()

for x in range(10):
    if x in (0, 1):
        x = "Values 0 and 1 caught here."
    elif x in (2,):
        x = "Value 2 caught here."
    elif x in (3, 7, 8):
        x = "Values 3, 7, 8 caught here."
    elif x in (4, 6):
        x = "Values 4 and 6 caught here"
    else:
        x = "Values 5 and 9 caught in default."
    print(x)

Fournit :

Dog has four legs
Cat has four legs
Bird has wings.
Bigfoot is a big mystery by default.
Dragonfly has wings.
Snake has a forked tongue.
Bat has wings.
Loch Ness Monster is a big mystery by default.

Values 0 and 1 caught here.
Values 0 and 1 caught here.
Value 2 caught here.
Values 3, 7, 8 caught here.
Values 4 and 6 caught here
Values 5 and 9 caught in default.
Values 4 and 6 caught here
Values 3, 7, 8 caught here.
Values 3, 7, 8 caught here.
Values 5 and 9 caught in default.

J'ai trouvé qu'une structure de commutateur commune :

switch ...parameter...
case p1: v1; break;
case p2: v2; break;
default: v3;

peut être exprimé en Python comme suit :

(lambda x: v1 if p1(x) else v2 if p2(x) else v3)

ou formaté de manière plus claire :

(lambda x:
     v1 if p1(x) else
     v2 if p2(x) else
     v3)

Au lieu d'être une instruction, la version Python est une expression qui correspond à une valeur.

Les solutions que j'utilise :

Une combinaison de 2 des solutions publiées ici, qui est relativement facile à lire et prend en charge les valeurs par défaut.

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}.get(whatToUse, lambda x: x - 22)(value)

.get('c', lambda x: x - 22)(23)

lève les yeux "lambda x: x - 2" dans le dict et l'utilise avec x=23

.get('xxx', lambda x: x - 22)(44)

ne le trouve pas dans le dict et utilise la valeur par défaut "lambda x: x - 22" avec x=44.

# simple case alternative

some_value = 5.0

# this while loop block simulates a case block

# case
while True:

    # case 1
    if some_value > 5:
        print ('Greater than five')
        break

    # case 2
    if some_value == 5:
        print ('Equal to five')
        break

    # else case 3
    print ( 'Must be less than 5')
    break

La plupart des réponses ici sont assez anciennes, et en particulier celles acceptées, cela semble donc mériter d'être mis à jour.

Tout d'abord, le fonctionnaire FAQ Python couvre cela et recommande le elif chaîne pour les cas simples et le dict pour des cas plus importants ou plus complexes.Il suggère également un ensemble de visit_ méthodes (un style utilisé par de nombreux frameworks de serveurs) dans certains cas :

def dispatch(self, value):
    method_name = 'visit_' + str(value)
    method = getattr(self, method_name)
    method()

La FAQ mentionne également PPE 275, qui a été écrit pour obtenir une décision officielle une fois pour toutes sur l'ajout d'instructions switch de style C.Mais ce PEP a en fait été reporté à Python 3, et il n'a été officiellement rejeté qu'en tant que proposition distincte, PEP 3103.La réponse a été bien sûr non, mais les deux PEP ont des liens vers des informations supplémentaires si vous êtes intéressé par les raisons ou l'historique.


Une chose qui est revenue plusieurs fois (et peut être vue dans la PEP 275, même si elle a été supprimée comme une véritable recommandation) est que si vous êtes vraiment dérangé par le fait d'avoir 8 lignes de code pour gérer 4 cas, contre.les 6 lignes que vous auriez en C ou en Bash, vous pouvez toujours écrire ceci :

if x == 1: print('first')
elif x == 2: print('second')
elif x == 3: print('third')
else: print('did not place')

Ce n'est pas exactement encouragé par PEP 8, mais c'est lisible et pas trop simple.


Au cours des plus d'une décennie écoulée depuis le rejet du PEP 3103, la question des déclarations de cas de style C, ou même de la version légèrement plus puissante de Go, a été considérée comme morte ;chaque fois que quelqu'un en parle sur python-ideas ou -dev, il est renvoyé à l'ancienne décision.

Cependant, l’idée d’une correspondance complète de modèles de style ML surgit toutes les quelques années, d’autant plus que des langages comme Swift et Rust l’ont adoptée.Le problème est qu’il est difficile de tirer un grand profit de la correspondance de modèles sans types de données algébriques.Bien que Guido ait été favorable à l'idée, personne n'a proposé de proposition qui s'intègre très bien dans Python.(Tu peux lire mon homme de paille de 2014 pour un exemple.) Cela pourrait changer avec dataclass en 3.7 et quelques propositions sporadiques pour un système plus puissant enum pour gérer les types de somme, ou avec diverses propositions pour différents types de liaisons locales d'instructions (comme PEP 3150, ou l'ensemble des propositions actuellement discutées sur -idées).Mais jusqu’à présent, ce n’est pas le cas.

Il existe aussi occasionnellement des propositions de correspondance de style Perl 6, qui est fondamentalement un méli-mélo de tout, depuis elif pour regex vers la commutation de type à répartition unique.

def f(x):
    dictionary = {'a':1, 'b':2, 'c':3}
    return dictionary.get(x,'Not Found') 
##Returns the value for the letter x;returns 'Not Found' if x isn't a key in the dictionary

j'ai aimé La réponse de Mark Bies

Depuis le x la variable doit être utilisée deux fois, j'ai modifié les fonctions lambda en sans paramètre.

je dois courir avec results[value](value)

In [2]: result = {
    ...:   'a': lambda x: 'A',
    ...:   'b': lambda x: 'B',
    ...:   'c': lambda x: 'C'
    ...: }
    ...: result['a']('a')
    ...: 
Out[2]: 'A'

In [3]: result = {
    ...:   'a': lambda : 'A',
    ...:   'b': lambda : 'B',
    ...:   'c': lambda : 'C',
    ...:   None: lambda : 'Nothing else matters'

    ...: }
    ...: result['a']()
    ...: 
Out[3]: 'A'

Modifier: J'ai remarqué que je peux utiliser None tapez avec avec des dictionnaires.Donc cela émulerait switch ; case else

Solution pour exécuter des fonctions :

result = {
    'case1':     foo1, 
    'case2':     foo2,
    'case3':     foo3,
    'default':   default,
}.get(option)()

où foo1(), foo2(), foo3() et default() sont des fonctions

def f(x):
     return 1 if x == 'a' else\
            2 if x in 'bcd' else\
            0 #default

Court et facile à lire, a une valeur par défaut et prend en charge les expressions dans les conditions et les valeurs de retour.

Elle est cependant moins efficace que la solution avec un dictionnaire.Par exemple, Python doit analyser toutes les conditions avant de renvoyer la valeur par défaut.

Je pense que la meilleure façon est de utilisez les idiomes du langage Python pour que votre code reste testable.Comme indiqué dans les réponses précédentes, j'utilise des dictionnaires pour tirer parti des structures et du langage Python et gardez le code "case" isolé dans différentes méthodes.Ci-dessous il y a une classe, mais vous pouvez utiliser directement un module, des globales et des fonctions.La classe a des méthodes qui peut être testé avec isolement.En fonction de vos besoins, vous pouvez également jouer avec des méthodes et des attributs statiques.

class ChoiceManager:

    def __init__(self):
        self.__choice_table = \
        {
            "CHOICE1" : self.my_func1,
            "CHOICE2" : self.my_func2,
        }

    def my_func1(self, data):
        pass

    def my_func2(self, data):
        pass

    def process(self, case, data):
        return self.__choice_table[case](data)

ChoiceManager().process("CHOICE1", my_data)

Il est possible de profiter de cette méthode en utilisant également les classes comme clés de "__choice_table".De cette façon, vous pouvez éviter abus d'instance et gardez tout propre et testable.

Supposons que vous deviez traiter un grand nombre de messages ou de paquets provenant du réseau ou de votre MQ.Chaque paquet possède sa propre structure et son code de gestion (de manière générique).Avec le code ci-dessus, il est possible de faire quelque chose comme ceci :

class PacketManager:

    def __init__(self):
        self.__choice_table = \
        {
            ControlMessage : self.my_func1,
            DiagnosticMessage : self.my_func2,
        }

    def my_func1(self, data):
        # process the control message here
        pass

    def my_func2(self, data):
        # process the diagnostic message here
        pass

    def process(self, pkt):
        return self.__choice_table[pkt.__class__](pkt)

pkt = GetMyPacketFromNet()
PacketManager().process(pkt)


# isolated test or isolated usage example
def test_control_packet():
    p = ControlMessage()
    PacketManager().my_func1(p)

Donc la complexité n'est pas répartie dans le flux de code mais elle est restituée dans la structure du code.

S'étendre sur Réponse de Greg Hewgill - On peut encapsuler la solution dictionnaire à l'aide d'un décorateur :

def case(callable):
    """switch-case decorator"""
    class case_class(object):
        def __init__(self, *args, **kwargs):
            self.args = args
            self.kwargs = kwargs

        def do_call(self):
            return callable(*self.args, **self.kwargs)

return case_class

def switch(key, cases, default=None):
    """switch-statement"""
    ret = None
    try:
        ret = case[key].do_call()
    except KeyError:
        if default:
            ret = default.do_call()
    finally:
        return ret

Ceci peut ensuite être utilisé avec le @case-décorateur

@case
def case_1(arg1):
    print 'case_1: ', arg1

@case
def case_2(arg1, arg2):
    print 'case_2'
    return arg1, arg2

@case
def default_case(arg1, arg2, arg3):
    print 'default_case: ', arg1, arg2, arg3

ret = switch(somearg, {
    1: case_1('somestring'),
    2: case_2(13, 42)
}, default_case(123, 'astring', 3.14))

print ret

La bonne nouvelle est que cela a déjà été fait NeoPySwitch-module.Installez simplement en utilisant pip :

pip install NeoPySwitch

Une solution que j'ai tendance à utiliser et qui utilise également des dictionnaires est :

def decision_time( key, *args, **kwargs):
    def action1()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action2()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action3()
        """This function is a closure - and has access to all the arguments"""
        pass

   return {1:action1, 2:action2, 3:action3}.get(key,default)()

Cela présente l'avantage de ne pas essayer d'évaluer les fonctions à chaque fois, et il suffit de s'assurer que la fonction externe obtient toutes les informations dont les fonctions internes ont besoin.

vous pouvez utiliser un dict distribué :

#!/usr/bin/env python


def case1():
    print("This is case 1")

def case2():
    print("This is case 2")

def case3():
    print("This is case 3")


token_dict = {
    "case1" : case1,
    "case2" : case2,
    "case3" : case3,
}


def main():
    cases = ("case1", "case3", "case2", "case1")
    for case in cases:
        token_dict[case]()


if __name__ == '__main__':
    main()

Sortir:

This is case 1
This is case 3
This is case 2
This is case 1

Simple, non testé ;chaque condition est évaluée indépendamment :il n'y a pas de chute, mais tous les cas sont évalués (bien que l'expression à activer ne soit évaluée qu'une seule fois), à moins qu'il n'y ait une instruction break.Par exemple,

for case in [expression]:
    if case == 1:
        print(end='Was 1. ')

    if case == 2:
        print(end='Was 2. ')
        break

    if case in (1, 2):
        print(end='Was 1 or 2. ')

    print(end='Was something. ')

impressions Was 1. Was 1 or 2. Was something. (Merde !Pourquoi ne puis-je pas avoir d'espaces de fin dans les blocs de code en ligne ?) si expression évalue à 1, Was 2. si expression évalue à 2, ou Was something. si expression évalue à autre chose.

Définir :

def switch1(value, options):
  if value in options:
    options[value]()

vous permet d'utiliser une syntaxe assez simple, avec les cas regroupés dans une carte :

def sample1(x):
  local = 'betty'
  switch1(x, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye," + local),
      print("!")),
    })

J'ai continué à essayer de redéfinir le commutateur d'une manière qui me permettrait de me débarrasser du "lambda :", mais j'ai abandonné.Modifier la définition :

def switch(value, *maps):
  options = {}
  for m in maps:
    options.update(m)
  if value in options:
    options[value]()
  elif None in options:
    options[None]()

M'a permis de mapper plusieurs cas sur le même code et de fournir une option par défaut :

def sample(x):
  switch(x, {
    _: lambda: print("other") 
    for _ in 'cdef'
    }, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye,"),
      print("!")),
    None: lambda: print("I dunno")
    })

Chaque cas répliqué doit figurer dans son propre dictionnaire ;switch() consolide les dictionnaires avant de rechercher la valeur.C'est toujours plus laid que je ne le souhaiterais, mais il a l'efficacité de base d'utiliser une recherche hachée sur l'expression, plutôt qu'une boucle sur toutes les clés.

Si vous ne craignez pas de perdre la coloration syntaxique dans les suites de cas, vous pouvez procéder comme suit :

exec {
    1: """
print ('one')
""", 
    2: """
print ('two')
""", 
    3: """
print ('three')
""",
}.get(value, """
print ('None')
""")

value est la valeur.En C, cela donnerait :

switch (value) {
    case 1:
        printf("one");
        break;
    case 2:
        printf("two");
        break;
    case 3:
        printf("three");
        break;
    default:
        printf("None");
        break;
}

Nous pouvons également créer une fonction d'assistance pour ce faire :

def switch(value, cases, default):
    exec cases.get(value, default)

Nous pouvons donc l'utiliser comme ceci pour l'exemple avec un, deux et trois :

switch(value, {
    1: """
print ('one')
    """, 
    2: """
print ('two')
    """, 
    3: """
print ('three')
    """,
}, """
print ('None')
""")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top