입력 인덱스 값에 따라 다른 고정 값을 반환하는 함수를 Python으로 작성하고 싶습니다.
다른 언어에서는 switch
또는 case
문을 사용하지만 Python에는 switch
문이 없는 것 같습니다. 이 시나리오에서 권장되는 Python 솔루션은 무엇입니까?
질문자 :Michael Schneider
입력 인덱스 값에 따라 다른 고정 값을 반환하는 함수를 Python으로 작성하고 싶습니다.
다른 언어에서는 switch
또는 case
문을 사용하지만 Python에는 switch
문이 없는 것 같습니다. 이 시나리오에서 권장되는 Python 솔루션은 무엇입니까?
아래의 원래 답변은 2008년에 작성되었습니다. 그 이후로 Python 3.10(2021)은 Python용 "스위치"의 일급 구현을 제공하는 match
- case
예를 들어:
def f(x): match x: case 'a': return 1 case 'b': return 2 case _: return 0 # 0 is the default case if x is not found
match
- case
문은 이 간단한 예보다 훨씬 더 강력합니다.
사전을 사용할 수 있습니다.
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 is not found
나는 항상 이렇게 하는 것을 좋아했다.
result = { 'a': lambda x: x * 5, 'b': lambda x: x + 7, 'c': lambda x: x - 2 }[value](x)
사전 방법(내가 정말 좋아하는 BTW) 외에도 if
- elif
- else
를 사용하여 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
물론 이것은 switch/case와 동일하지 않습니다. break
문을 생략하는 것만큼 쉽게 fall-through를 가질 수는 없지만 더 복잡한 테스트를 할 수는 있습니다. 그것의 형식은 기능적으로 그것이 더 가깝지만 if
Python >= 3.10 (시험판)
와우, 파이썬은 이제 진정한 match
/ case
구문을 얻고 있습니다!
PEP 634 , '구조적 패턴 매칭'; 일명 switch
/ case
가 승인되어 Python 3.10에 추가되었습니다.
샘플 사용법 :
match something: case 0 | 1 | 2: # Matches 0, 1 or 2 print("Small number") case [] | [_]: # Matches an empty or single value sequence # Matches lists and tuples but not sets print("A short sequence") case str() | bytes(): # Something of `str` or `bytes` type print("Something string-like") case _: # Anything not matched by the above print("Something else")
파이썬 <= 3.9
스위치/케이스에 대한 내가 가장 좋아하는 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.
내가 가장 좋아하는 것은 정말 좋은 레시피 입니다. 이것은 특히 기능에서 실제 switch case 문에 내가 본 것과 가장 가깝습니다.
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!"
with foo as case
아닌 대소문자를 사용하는 컨텍스트 관리자 솔루션 for case in foo
수 있고 큰 스위치 명령문의 경우 2차 동작이 아닌 선형 동작이 좋은 터치일 수 있음을 나타냅니다. for 루프가 있는 이 답변의 가치 중 일부는 중단 및 폴스루(fallthrough)를 가질 수 있는 기능이며, 키워드 선택을 조금 사용하려는 경우 컨텍스트 관리자에서도 이를 얻을 수 있습니다.
class Switch: def __init__(self, value): self.value = value self._entered = False self._broken = False self._prev = None def __enter__(self): return self def __exit__(self, type, value, traceback): return False # Allows a traceback to occur def __call__(self, *values): if self._broken: return False if not self._entered: if values and self.value not in values: return False self._entered, self._prev = True, values return True if self._prev is None: self._prev = values return True if self._prev != values: self._broken = True return False if self._prev == values: self._prev = None return False @property def default(self): return self()
다음은 예입니다.
# Prints 'bar' then 'baz'. with Switch(2) as case: while case(0): print('foo') while case(1, 2, 3): print('bar') while case(4, 5): print('baz') break while case.default: print('default') break
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
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'
)이 표시됩니다. ['HELO', 'foo.bar.com']
과 같은 parts
으로 토큰화됩니다. 실제 메서드 조회 이름은 parts[0]
에서 가져옵니다.
(원래의 메서드는 state_COMMAND
. 왜냐하면 동일한 패턴을 사용하여 상태 머신을 구현하기 때문입니다. 즉, getattr(self, 'state_' + self.mode)
)
값을 반환하는 것이 아니라 개체에서 무언가를 변경하는 메서드를 사용하고 싶다고 가정해 보겠습니다. 여기에 명시된 접근 방식을 사용하면 다음과 같습니다.
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에 명시된 원칙에서 크게 파생되었습니다.
기능을 실행하는 솔루션:
result = { 'case1': foo1, 'case2': foo2, 'case3': foo3, }.get(option)(parameters_optional)
여기서 foo1(), foo2() 및 foo3()은 함수입니다.
예 1 (매개변수 포함):
option = number['type'] result = { 'number': value_of_int, # result = value_of_int(number['value']) 'text': value_of_text, # result = value_of_text(number['value']) 'binary': value_of_bin, # result = value_of_bin(number['value']) }.get(option)(value['value'])
예 2 (매개변수 없음):
option = number['type'] result = { 'number': func_for_number, # result = func_for_number() 'text': func_for_text, # result = func_for_text() 'binary': func_for_bin, # result = func_for_bin() }.get(option)()
"switch"로 추가 문을 검색하는 경우 Python을 확장하는 Python 모듈을 빌드했습니다. "파이썬을 위한 향상된 구조"로 ESPY 라고 하며 파이썬 2.x와 파이썬 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
복잡한 케이스 블록이 있는 경우 함수 사전 조회 테이블 사용을 고려할 수 있습니다...
이전에 이 작업을 수행하지 않았다면 디버거로 들어가서 사전이 각 기능을 어떻게 찾는지 정확히 보는 것이 좋습니다.
참고: 케이스/사전 조회 내에서 "()"를 사용하지 마십시오. 그렇지 않으면 사전/케이스 블록이 생성될 때 각 기능이 호출됩니다. 해시 스타일 조회를 사용하여 각 함수를 한 번만 호출하기를 원하기 때문에 이것을 기억하십시오.
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()
여기에 있는 대부분의 답변은 꽤 오래되었고 특히 허용된 답변이므로 업데이트할 가치가 있는 것 같습니다.
첫째, 공식 Python FAQ에서 이를 다루며 간단한 경우에는 elif
체인을 권장하고 더 크거나 복잡한 경우에는 dict
또한 경우에 따라 일련의 visit_
메서드(많은 서버 프레임워크에서 사용하는 스타일)를 제안합니다.
def dispatch(self, value): method_name = 'visit_' + str(value) method = getattr(self, method_name) method()
FAQ에는 C 스타일 스위치 문 추가에 대한 공식적인 결정을 내리기 위해 작성된 PEP 275 도 언급되어 있습니다. 그러나 그 PEP는 실제로 Python 3으로 연기되었으며 별도의 제안인 PEP 3103 으로 공식적으로 거부되었습니다. 대답은 물론 아니오였습니다. 하지만 두 PEP에는 이유나 이력에 관심이 있는 경우 추가 정보에 대한 링크가 있습니다.
여러 번 등장한 한 가지(실제 권장 사항으로 잘려진 경우에도 PEP 275에서 볼 수 있음) C 또는 Bash에 있는 줄에서 항상 다음과 같이 작성할 수 있습니다.
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 스타일의 case 문 또는 Go의 약간 더 강력한 버전의 문제는 죽은 것으로 간주되었습니다. 누군가 python-ideas 또는 -dev에 대해 언급할 때마다 이전 결정을 참조합니다.
그러나 완전한 ML 스타일 패턴 일치에 대한 아이디어는 특히 Swift 및 Rust와 같은 언어에서 채택한 이후 몇 년마다 발생합니다. 문제는 대수적 데이터 유형 없이는 패턴 매칭을 많이 활용하기 어렵다는 것입니다. 귀도는 그 아이디어에 공감했지만, 아무도 파이썬에 잘 맞는 제안을 내놓지 못했습니다. (예를 들어 내 2014년 스트로맨 을 읽을 수 있습니다 dataclass
와 합계 유형을 처리하기 위한 보다 강력한 enum
에 대한 산발적인 제안 또는 다양한 종류의 명령문-로컬 바인딩(예: PEP 3150 , 또는 현재 논의 중인 일련의 제안서). 그러나 지금까지는 그렇지 않았습니다.
elif
에서 정규식, 단일 디스패치 유형 전환에 이르기까지 모든 것을 뒤섞은 Perl 6 스타일 일치에 대한 제안도 있습니다.
"dict as switch" 아이디어 확장. 스위치에 기본값을 사용하려는 경우:
def f(x): try: return { 'a': 1, 'b': 2, }[x] except KeyError: return 'default'
나는 일반적인 스위치 구조를 발견했습니다:
switch ...parameter... case p1: v1; break; case p2: v2; break; default: v3;
파이썬으로 다음과 같이 표현할 수 있습니다.
(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 버전은 값으로 평가되는 표현식입니다.
내가 사용하는 솔루션:
여기에 게시된 2가지 솔루션의 조합으로, 비교적 읽기 쉽고 기본값을 지원합니다.
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"
x=23
과 함께 사용합니다.
.get('xxx', lambda x: x - 22)(44)
dict에서 찾지 못하고 x=44
"lambda x: x - 22"
사용합니다.
Google 검색에서 내가 찾고 있던 간단한 답변을 찾지 못했습니다. 하지만 어쨌든 알아냈습니다. 정말 간단합니다. 그것을 게시하기로 결정하고 다른 사람의 머리에 약간의 흠집을 방지 할 수 있습니다. 핵심은 단순히 "in"과 튜플입니다. 다음은 RANDOM fall-through를 포함한 fall-through를 사용한 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.
# 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
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
발송된 사전을 사용할 수 있습니다.
#!/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
Mark Bies의 답변이 마음에 들었습니다.
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
def f(x): return 1 if x == 'a' else\ 2 if x in 'bcd' else\ 0 #default
짧고 읽기 쉽고 기본값이 있으며 조건 및 반환 값 모두에서 표현식을 지원합니다.
그러나 사전이 있는 솔루션보다 효율성이 떨어집니다. 예를 들어 Python은 기본값을 반환하기 전에 모든 조건을 스캔해야 합니다.
간단하고 테스트되지 않았습니다. 각 조건은 독립적으로 평가됩니다. 대체는 없지만 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.
(젠장! 인라인 코드 블록에 왜 후행 공백이 없을까요?) if expression
이 1
평가되면 Was 2.
if expression
이 2
평가되거나 Was something.
expression
다른 것으로 평가되는 경우.
지금까지 "파이썬에는 스위치가 없습니다. 이렇게 하세요"라는 답변이 많이 있습니다. 그러나 switch 문 자체는 게으른 프로그래밍을 조장하기 때문에 대부분의 경우 피할 수 있고 피해야 하는 쉽게 남용되는 구조라는 점을 지적하고 싶습니다. 지목 사항:
def ToUpper(lcChar): if (lcChar == 'a' or lcChar == 'A'): return 'A' elif (lcChar == 'b' or lcChar == 'B'): return 'B' ... elif (lcChar == 'z' or lcChar == 'Z'): return 'Z' else: return None # or something
이제 switch-statement로 이 작업을 수행할 수 있지만(Python이 제공하는 경우) 이 작업을 제대로 수행하는 메서드가 있기 때문에 시간을 낭비하게 됩니다. 또는 덜 분명한 것이 있습니다.
def ConvertToReason(code): if (code == 200): return 'Okay' elif (code == 400): return 'Bad Request' elif (code == 404): return 'Not Found' else: return None
그러나 이러한 종류의 작업은 사전을 사용하여 처리할 수 있고 처리해야 합니다. 사전을 사용하면 더 빠르고 덜 복잡하고 오류가 발생하기 쉽고 간결하기 때문입니다.
그리고 switch 문에 대한 대부분의 "사용 사례"는 이 두 가지 경우 중 하나에 속합니다. 문제에 대해 철저히 생각했다면 사용할 이유가 거의 없습니다.
따라서 "Python에서 어떻게 전환합니까?"라고 묻는 대신 "왜 Python으로 전환하고 싶습니까?"라고 물어야 할 것입니다. 왜냐하면 그것은 종종 더 흥미로운 질문이고 당신이 만들고 있는 모든 디자인의 결함을 종종 드러낼 것이기 때문입니다.
그렇다고 스위치를 절대 사용해서는 안 된다는 말은 아닙니다. 상태 머신, 렉서, 파서 및 오토마타는 모두 이를 어느 정도 사용하며 일반적으로 대칭 입력에서 시작하여 비대칭 출력으로 이동할 때 유용할 수 있습니다. 당신은 당신의 코드에서 못을 많이 볼 수 있기 때문에 당신이 망치로 스위치를 사용하지 않는지 확인해야 합니다.
사전도 사용하는 내가 사용하는 경향이 있는 솔루션은 다음과 같습니다.
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)()
이것은 매번 함수를 평가하려고 하지 않는다는 장점이 있으며 외부 함수가 내부 함수에 필요한 모든 정보를 얻도록 해야 합니다.
수락 된 답변을 읽은 후 상당히 혼란 스러웠지만 모든 것이 해결되었습니다.
def numbers_to_strings(argument): switcher = { 0: "zero", 1: "one", 2: "two", } return switcher.get(argument, "nothing")
이 코드는 다음과 유사합니다.
function(argument){ switch(argument) { case 0: return "zero"; case 1: return "one"; case 2: return "two"; default: return "nothing"; } }
함수에 대한 사전 매핑에 대한 자세한 내용은 소스 를 확인하십시오.
정의:
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()는 값을 찾기 전에 사전을 통합합니다. 내가 원하는 것보다 여전히 못생겼지만 모든 키를 순환하는 대신 표현식에 대해 해시된 조회를 사용하는 기본 효율성이 있습니다.
Greg Hewgill의 답변 확장 - 데코레이터를 사용하여 사전 솔루션을 캡슐화할 수 있습니다.
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
좋은 소식은 이것이 이미 NeoPySwitch -module 에서 수행되었다는 것입니다. 간단히 pip를 사용하여 설치하십시오.
pip install NeoPySwitch
출처 : http:www.stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python
무엇인가요 ":-!!" C 코드에서? (0) | 2022.01.06 |
---|---|
find 에서 디렉토리를 제외하는 방법. 명령 (0) | 2022.01.06 |
JavaScript에서 "잘못된 날짜" 날짜 인스턴스 감지 (0) | 2022.01.06 |
Git으로 파일의 이전 버전을 보려면 어떻게 해야 합니까? (0) | 2022.01.06 |
지도 정렬<Key, Value> 값으로 (0) | 2022.01.06 |