문제

입력 인덱스 값에 따라 다른 고정 값을 반환하는 함수를 Python으로 작성하고 싶습니다.

다른 언어에서는 switch 또는 case 명령문이 있지만 Python에는 switch 성명.이 시나리오에서 권장되는 Python 솔루션은 무엇입니까?

도움이 되었습니까?

해결책

사전을 사용할 수 있습니다.

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

다른 팁

기본값을 원하면 사전을 사용할 수 있습니다 get(key[, default]) 방법:

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

나는 항상 이런 식으로 하는 걸 좋아했어요.

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

여기에서

사전 메서드(제가 정말 좋아하는 BTW) 외에도 if-elif-else를 사용하여 스위치/케이스/기본 기능을 얻을 수도 있습니다.

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

물론 이것은 스위치/케이스와 동일하지 않습니다. 중단을 벗어나는 것만큼 쉽게 넘어질 수는 없습니다.하지만 더 복잡한 테스트를 할 수도 있습니다.기능적으로는 그것이 더 가깝지만 형식은 일련의 중첩된 ifs보다 더 좋습니다.

내가 가장 좋아하는 스위치/케이스 Python 레시피는 다음과 같습니다.

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

간단한 시나리오에서는 짧고 간단합니다.

11줄 이상의 C 코드와 비교:

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

튜플을 사용하여 여러 변수를 할당할 수도 있습니다.

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

용법:

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

테스트:

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

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'

토큰을 전달하고 확장된 코드를 실행해야 할 때마다 이를 사용할 수 있습니다.상태 머신에서는 state_ 방법 및 파견 self.state.이 스위치는 기본 클래스에서 상속하고 직접 정의하여 깔끔하게 확장할 수 있습니다. do_ 행동 양식.종종 당신은 가지고 있지 않을 것입니다 do_ 기본 클래스의 메서드.

편집하다:그게 정확히 어떻게 사용되는거야?

SMTP의 경우 수신됩니다. HELO 전선에서.관련 코드 (에서 twisted/mail/smtp.py, 우리의 경우에 맞게 수정됨)은 다음과 같습니다

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

당신은 받게됩니다 ' HELO foo.bar.com ' (또는 당신은 얻을 수 있습니다 'QUIT' 또는 'RCPT TO: foo').이는 토큰화됩니다. parts ~처럼 ['HELO', 'foo.bar.com'].실제 메소드 조회 이름은 다음에서 가져옵니다. parts[0].

(원래 방법은 또한 state_COMMAND, 상태 머신을 구현하는 데 동일한 패턴을 사용하기 때문입니다. getattr(self, 'state_' + self.mode))

내가 제일 좋아하는 건 정말 좋은 거야 레시피.당신은 정말 그것을 좋아할 것입니다.특히 기능에서 실제 스위치 케이스 설명과 가장 가까운 것입니다.

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

예는 다음과 같습니다.

# 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

단순히 값을 반환하는 것이 아니라 객체의 내용을 변경하는 메서드를 사용하고 싶다고 가정해 보겠습니다.여기에 명시된 접근 방식을 사용하면 다음과 같습니다.

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

여기서 일어나는 일은 Python이 사전의 모든 메소드를 평가한다는 것입니다.따라서 값이 'a'인 경우에도 개체가 증가합니다. 그리고 x만큼 감소합니다.

해결책:

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

result = func(*args)

따라서 함수와 해당 인수가 포함된 목록을 얻습니다.이렇게 하면 함수 포인터와 인수 목록만 반환됩니다. ~ 아니다 평가되었습니다.그런 다음 'result'는 반환된 함수 호출을 평가합니다.

여기에 2센트를 투자하겠습니다.Python에 Case/Switch 문이 없는 이유는 Python이 '무언가를 수행하는 올바른 방법은 단 하나'라는 원칙을 따르기 때문입니다.따라서 스위치/케이스 기능을 다시 만드는 다양한 방법을 생각해낼 수 있지만 이를 수행하는 Python 방식은 if/elif 구성입니다.즉

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

나는 PEP 8이 여기서 고개를 끄덕일 가치가 있다고 느꼈습니다.Python의 아름다운 점 중 하나는 단순함과 우아함입니다.이는 "무언가를 수행하는 올바른 방법은 단 하나뿐입니다"를 포함하여 PEP 8에 제시된 원칙에서 크게 파생되었습니다.

"dict as switch" 아이디어를 확장합니다.스위치에 기본값을 사용하려는 경우:

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

복잡한 케이스 블록이 있는 경우 함수 사전 조회 테이블 사용을 고려할 수 있습니다.

이전에 이 작업을 수행하지 않았다면 디버거를 실행하여 사전이 각 함수를 어떻게 찾는지 정확하게 확인하는 것이 좋습니다.

메모:하다 ~ 아니다 사례/사전 조회 내에서 "()"를 사용하거나 사전/사전 블록이 생성될 때 각 함수를 호출합니다.해시 스타일 조회를 사용하여 각 함수를 한 번만 호출하려고 하기 때문에 이를 기억하세요.

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

"switch"와 같은 추가 명령문을 검색하는 경우 Python을 확장하는 Python 모듈을 구축했습니다.그것은 ~라고 불린다 ESPY "Python을 위한 향상된 구조"로 Python 2.x와 Python 3.x 모두에서 사용할 수 있습니다.

예를 들어, 이 경우 다음 코드로 switch 문을 수행할 수 있습니다.

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

다음과 같이 사용할 수 있습니다.

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

그래서 espy는 Python에서 다음과 같이 번역합니다.

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

Google 검색 어디에서도 제가 찾고 있던 간단한 답변을 찾을 수 없었습니다.하지만 어쨌든 알아냈어요.정말 간단합니다.게시하기로 결정하고, 아마도 다른 사람의 머리에 긁힌 자국을 조금이라도 예방할 수 있을 것입니다.핵심은 단순히 "in"과 튜플입니다.다음은 RANDOM fallthrough를 포함하여 fallthrough를 사용한 switch 문 동작입니다.

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)

다음을 제공합니다:

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.

일반적인 스위치 구조를 발견했습니다.

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

Python에서는 다음과 같이 표현할 수 있습니다.

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

또는 더 명확한 방식으로 형식을 지정합니다.

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

명령문이 아닌 Python 버전은 값으로 평가되는 표현식입니다.

내가 사용하는 솔루션:

여기에 게시된 두 가지 솔루션의 조합은 비교적 읽기 쉽고 기본값을 지원합니다.

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)

올려다본다 "lambda x: x - 2" dict에서 그것을 사용합니다. x=23

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

dict에서 찾지 못하고 기본값을 사용합니다. "lambda x: x - 22" ~와 함께 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

여기에 있는 대부분의 답변은 꽤 오래되었으며 특히 허용되는 답변이므로 업데이트할 가치가 있는 것 같습니다.

먼저, 공식 파이썬 FAQ 이 내용을 다루고 다음을 권장합니다. elif 간단한 케이스를 위한 체인과 dict 더 크거나 더 복잡한 경우.또한 세트를 제안합니다. visit_ 경우에 따라 메서드(많은 서버 프레임워크에서 사용되는 스타일):

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

FAQ에도 언급되어 있습니다. PEP 275, C 스타일 스위치 문 추가에 대한 공식적인 결정을 내리기 위해 작성되었습니다.하지만 그 PEP는 실제로 Python 3으로 연기되었으며 별도의 제안으로 공식적으로 거부되었습니다. PEP 3103.물론 대답은 '아니요'였습니다. 하지만 이유나 기록에 관심이 있는 경우 두 PEP에 추가 정보에 대한 링크가 있습니다.


여러 번 나온 한 가지(실제 권장 사항으로 생략되었지만 PEP 275에서 볼 수 있음)는 4가지 사례를 처리하기 위해 8줄의 코드를 사용하는 것이 정말로 귀찮은 경우와C나 Bash에 있는 6줄은 언제든지 다음과 같이 작성할 수 있습니다.

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

이는 PEP 8에서 권장되는 것은 아니지만 읽기 쉽고 너무 단조롭지 않습니다.


PEP 3103이 거부된 지 10년이 넘도록 C 스타일 사례 설명 또는 Go의 약간 더 강력한 버전 문제는 죽은 것으로 간주되었습니다.누구든지 python-ideas 또는 -dev에 대해 언급할 때마다 이전 결정이 언급됩니다.

그러나 완전한 ML 스타일 패턴 일치에 대한 아이디어는 특히 Swift 및 Rust와 같은 언어가 이를 채택한 이후 몇 년마다 등장합니다.문제는 대수적 데이터 유형이 없으면 패턴 일치를 많이 활용하기 어렵다는 것입니다.Guido는 이 아이디어에 공감했지만, Python에 잘 맞는 제안을 제시한 사람은 아무도 없습니다.(당신은 읽을 수있다 나의 2014년 스트로맨 예를 들어.) 이는 다음과 같이 변경될 수 있습니다. dataclass 3.7에서는 좀 더 강력한 기능을 위한 산발적인 제안이 있었습니다. enum 합계 유형을 처리하거나 다양한 종류의 명령문-지역 바인딩에 대한 다양한 제안(예: PEP 3150, 또는 현재 -ideas에서 논의되고 있는 제안 세트).하지만 지금까지는 그렇지 않았습니다.

기본적으로 Perl 6 스타일 매칭에 대한 제안도 가끔 있습니다. elif 단일 디스패치 유형 전환으로 정규식을 지정합니다.

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

좋아 했어요 마크 비즈의 답변

이후 x 변수를 두 번 사용해야 하므로 람다 함수를 매개변수 없는 것으로 수정했습니다.

나는 함께 달려야 해 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'

편집하다: 사용할 수 있다는 것을 알았습니다 None 사전으로 입력하세요.그래서 이것은 에뮬레이트됩니다 switch ; case else

기능 실행 솔루션:

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

여기서 foo1(), foo2(), foo3() 및 default()는 함수입니다.

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

짧고 읽기 쉬우며 기본값이 있으며 조건과 반환 값 모두에서 표현식을 지원합니다.

그러나 사전을 사용하는 솔루션보다 효율성이 떨어집니다.예를 들어 Python은 기본값을 반환하기 전에 모든 조건을 검사해야 합니다.

내 생각에 가장 좋은 방법은 Python 언어 관용구를 사용하여 코드를 테스트 가능하게 유지하세요..이전 답변에서 볼 수 있듯이 사전을 사용하여 파이썬 구조와 언어를 활용하세요 "케이스" 코드를 다른 방법으로 분리하여 유지하세요.아래에는 클래스가 있지만 모듈, 전역 및 함수를 직접 사용할 수 있습니다.클래스에는 다음과 같은 메소드가 있습니다. 격리하여 테스트할 수 있습니다..필요에 따라 정적 메서드와 속성을 사용할 수도 있습니다.

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)

가능하다 클래스도 키로 사용하여 이 방법을 활용하세요. "__choice_table"의 것입니다.이런 식으로 피할 수 있습니다 인스턴스 남용 모두 깨끗하고 테스트 가능하게 유지하세요.

네트나 MQ에서 많은 메시지나 패킷을 처리해야 한다고 가정해 보겠습니다.모든 패킷에는 고유한 구조와 관리 코드(일반적인 방식)가 있습니다.위의 코드를 사용하면 다음과 같은 작업이 가능합니다.

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)

그래서 복잡성은 코드 흐름에서 확산되지 않지만 코드 구조에서 렌더링됩니다..

확장 중 그렉 휴길의 답변 - 데코레이터를 사용하여 사전 솔루션을 캡슐화할 수 있습니다.

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

그런 다음 다음과 함께 사용할 수 있습니다. @case-데코레이터

@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

좋은 소식은 이 작업이 이미 2019년에 완료되었다는 것입니다. 네오파이스위치-기준 치수.pip를 사용하여 간단히 설치하십시오.

pip install NeoPySwitch

사전을 활용하면서 내가 자주 사용하는 솔루션은 다음과 같습니다.

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

이는 매번 함수를 평가하려고 하지 않고 외부 함수가 내부 함수에 필요한 모든 정보를 얻는지만 확인하면 된다는 장점이 있습니다.

발송된 dict를 사용할 수 있습니다:

#!/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()

산출:

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

간단하고 테스트되지 않았습니다.각 조건은 독립적으로 평가됩니다.fall-through는 없지만 break 문이 없는 한 모든 경우가 평가됩니다(비록 스위치를 켜는 표현식은 한 번만 평가되지만).예를 들어,

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. ')

인쇄물 Was 1. Was 1 or 2. Was something. (젠장!인라인 코드 블록에 후행 공백이 없는 이유는 무엇입니까?) 만약에 expression 평가하다 1, Was 2. 만약에 expression 평가하다 2, 또는 Was something. 만약에 expression 다른 것으로 평가합니다.

정의:

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

사례를 맵에 묶어서 매우 간단한 구문을 사용할 수 있습니다.

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

나는 "lambda:"를 제거할 수 있는 방식으로 스위치를 재정의하려고 계속 노력했지만 포기했습니다.정의 조정:

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

여러 사례를 동일한 코드에 매핑하고 기본 옵션을 제공할 수 있게 되었습니다.

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")
    })

복제된 각 사례는 자체 사전에 있어야 합니다.switch()는 값을 찾기 전에 사전을 통합합니다.내가 원하는 것보다 여전히 더 보기 흉하지만 모든 키를 순환하는 대신 표현식에 해시된 조회를 사용하는 기본 효율성이 있습니다.

사례 모음 내에서 구문 강조 표시가 손실되는 것을 걱정하지 않으려면 다음을 수행할 수 있습니다.

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

어디 value 값입니다.C에서는 다음과 같습니다.

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

이를 수행하기 위해 도우미 함수를 만들 수도 있습니다.

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

따라서 1, 2, 3이 포함된 예에서는 다음과 같이 사용할 수 있습니다.

switch(value, {
    1: """
print ('one')
    """, 
    2: """
print ('two')
    """, 
    3: """
print ('three')
    """,
}, """
print ('None')
""")
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top