当前位置:   article > 正文

python如何实现switch_python switch

python switch

我们知道,python是没有switch语句的,所以当我们要实现这样结构的逻辑时:

  1. var index = 10
  2. switch index {
  3. case 100 :
  4. print( "index 的值为 100")
  5. case 10,15 :
  6. print( "index 的值为 10 或 15")
  7. case 5 :
  8. print( "index 的值为 5")
  9. default :
  10. print( "默认 case")
  11. }

经常需要用多个if-else来实现。除此之外,我们还可以考虑用字典对应提取的方式来实现,下面我们给出四种实现switch的方法,并对比这四种方法的运行时间

  1. something = 'something'
  2. # 第一种,多次使用if-else结构
  3. if something == 'this':
  4. the_thing = 1
  5. elif something == 'that':
  6. the_thing = 2
  7. elif something == 'there':
  8. the_thing = 3
  9. else:
  10. the_thing = 4
  11. # 第二种,用get设置默认值的字典提取
  12. options = {'this': 1, 'that': 2, 'there': 3}
  13. the_thing = options.get(something, 4)
  14. # 第三种,用if-else配合不设置默认值的字典提取
  15. options = {'this': 1, 'that': 2, 'there': 3}
  16. if something in options:
  17. the_thing = options[something]
  18. else:
  19. the_thing = 4
  20. # 第四种,用collections模块设置默认值进行字典提取
  21. from collections import defaultdict
  22. default_options = defaultdict(lambda: 4, {'this': 1, 'that': 2, 'there': 3})
  23. the_thing = default_options[something]

下面我们对比一下这几种方式提取的速度,分成两种情况

  • 判断的内容在字典中
  • 判断的内容不在字典中

在ifelse.py文件中输入如下内容

  1. import time
  2. from collections import defaultdict
  3. # 计算运行时间的装饰器
  4. def run_time(func):
  5. def wrapper(*args, **kw):
  6. start = time.time()
  7. func(*args, **kw)
  8. end = time.time()
  9. print('running', end-start, 's')
  10. return wrapper
  11. # 准备好两个字典
  12. options = {'this': 1, 'that': 2, 'there': 3}
  13. default_options = defaultdict(lambda: 4, {'this': 1, 'that': 2, 'there': 3})
  14. # 四种方法都定义成函数
  15. # 接受参数something即待判断值
  16. # 每次循环10000000
  17. @run_time
  18. def first(something):
  19. for i in range(10000000):
  20. if something == 'this':
  21. the_thing = 1
  22. elif something == 'that':
  23. the_thing = 2
  24. elif something == 'there':
  25. the_thing = 3
  26. else:
  27. the_thing = 4
  28. @run_time
  29. def second(something):
  30. for i in range(10000000):
  31. the_thing = options.get(something, 4)
  32. @run_time
  33. def third(something):
  34. for i in range(10000000):
  35. if something in options:
  36. the_thing = options[something]
  37. else:
  38. the_thing = 4
  39. @run_time
  40. def forth(something):
  41. for i in range(10000000):
  42. the_thing = default_options[something]
  43. # 调用函数
  44. if __name__ == '__main__':
  45. # 判断的内容不在字典中
  46. first('something')
  47. second('something')
  48. third('something')
  49. forth('something')
  50. print('-'*20)
  51. # 判断的内容在字典中
  52. first('this')
  53. second('this')
  54. third('this')
  55. forth('this')

在命令行多次运行

python ifelse.py

得到结果如下

  1. -------------第一次---------------
  2. running 1.8487958908081055 s
  3. running 1.63755202293396 s
  4. running 0.7807505130767822 s
  5. running 0.6786513328552246 s
  6. --------------------
  7. running 0.7807483673095703 s
  8. running 2.075996160507202 s
  9. running 1.0349910259246826 s
  10. running 0.740731954574585 s
  11. -------------第二次---------------
  12. running 1.7757258415222168 s
  13. running 1.6395549774169922 s
  14. running 0.8408102989196777 s
  15. running 0.7977871894836426 s
  16. --------------------
  17. running 0.710662841796875 s
  18. running 1.9098539352416992 s
  19. running 1.042982578277588 s
  20. running 0.8197875022888184 s
  21. -------------第三次---------------
  22. running 1.5885050296783447 s
  23. running 1.8237719535827637 s
  24. running 0.9819226264953613 s
  25. running 0.78375244140625 s
  26. --------------------
  27. running 0.6226155757904053 s
  28. running 1.634549617767334 s
  29. running 0.947911262512207 s
  30. running 0.6586313247680664 s

从结果中可以看出
1.四种方法之间的对比,后两种方法明显比前两种方法快,且最后一种方法总是最快的。
2.待判断内容是否在字典中设置的对比

  • 第一种全程if-else判断的情况下,早判断出来程序就会早结束,所以if-else判断的内容顺序是有讲究的
  • 而从字典里提取则没有看出显著的不同

由于使用collections模块中的defaultdict虽然最快,但是会占用较多内存,所以最推荐的是第三种方法,使用if-else配合无默认字典提取方法。

在Python中,没有内置的switch语句,但是可以使用多种方式实现类似switch的操作。以下是几种实现方法:

  1. 使用字典:
 
  1. pythondef switch(key):
  2. return {
  3. 'a': 'case a',
  4. 'b': 'case b',
  5. 'c': 'case c',
  6. }.get(key, 'default')
  7. print(switch('a')) # 输出: case a
  8. print(switch('d')) # 输出: default
  1. 使用 if-elif-else 语句:
 
  1. pythondef switch(key):
  2. if key == 'a':
  3. return 'case a'
  4. elif key == 'b':
  5. return 'case b'
  6. elif key == 'c':
  7. return 'case c'
  8. else:
  9. return 'default'
  10. print(switch('a')) # 输出: case a
  11. print(switch('d')) # 输出: default
  1. 使用函数装饰器和字典:
 
  1. pythondef switch(key):
  2. @dict_of_functions.get(key, lambda: 'default')
  3. def default():
  4. return 'case a'
  5. def case_b():
  6. return 'case b'
  7. def case_c():
  8. return 'case c'
  9. dict_of_functions = {
  10. 'a': default,
  11. 'b': case_b,
  12. 'c': case_c,
  13. }
  14. return switch(key)()
  15. print(switch('a')) # 输出: case a
  16. print(switch('d')) # 输出: default
  1. 使用类装饰器和字典:
 
  1. pythonclass Switch:
  2. def __init__(self, key):
  3. self.key = key
  4. @property
  5. def case(self):
  6. return {
  7. 'a': 'case a',
  8. 'b': 'case b',
  9. 'c': 'case c',
  10. }.get(self.key, 'default')
  11. print(Switch('a').case) # 输出: case a
  12. print(Switch('d').case) # 输出: default

以上就是Python中实现类似switch操作的几种方法。

python语言中,没有内置switch函数,如果用if-else语句的话,当分支数量很大时,会显得很臃肿,下面是使用python中的字典,实现switch语句功能的方法。

  1. # 设置flag的值,用于选择执行哪个函数
  2. flag = 0
  3. # 设置自定义函数
  4. def get_function_1():
  5. # 函数功能
  6. return 'Function_1'
  7. def get_function_2():
  8. # 函数功能
  9. return 'Function_2'
  10. def get_function_3():
  11. # 函数功能
  12. return 'Function_3'
  13. def get_default():
  14. # 函数功能
  15. return 'Others'
  16. # 字典中不同的值对应不同的自定义函数
  17. switcher = {
  18. 0: get_function_1,
  19. 1: get_function_2,
  20. 2: get_function_3
  21. }
  22. # 根据flag的值决定执行哪一个函数,如果输入的值在字典中没有,则执行get_default函数
  23. output = switcher.get(flag, get_default)()
  24. print("The output of switcher is: ", output)

如果语句不复杂,也可以使用lambda表达式,可以使代码更简洁,lambda表达式介绍见

Python lambda介绍 - Goodpy - 博客园​www.cnblogs.com/evening/archive/2012/03/29/2423554.html

下面是利用了字典和lambda表达式,实现switch语句功能

  1. flag = 0
  2. # 如果字典中没有flag的值,则执行get_default函数
  3. def get_default(x):
  4. # 函数功能
  5. return 'None'
  6. switcher = {
  7. 0: lambda x:x+1,
  8. 1: lambda x:x**2,
  9. 2: lambda x:abs(x)
  10. }
  11. output = switcher.get(flag, get_default)(5)
  12. print("The output of switcher is: ", output)

作者:书海阅读岛
链接:https://www.zhihu.com/question/591024612/answer/2953371599
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

Python已有特性

  1. Python中的函数是可以作为变量存在的,也就是可以将函数复制给变量,变量可以作为字典的value存在,也就是函数可以作为字典的value,对应了switch中的基本特性1
  2. if-else可以让程序存在多种不同的分支,可以用来实现基本特性2中的默认逻辑
  3. 字典的key和value是一对一或者多对一的,就是每个key对应一个value,但是一个value可以有多个key;这点对应了switch的基本特性3

需要添加的特性

从Python已有特性上来说,我们看起来不需要添加什么新的新特性,只需要把已有特性组合下就行

组合特性

这里以一个课本中的题目来做例子:百分制转字母分,也就是——90分及以上是A,80分及以上是B,70分及以上是C,60分及以上是D,60分以下都是E

  1. 定义一个字典,key是条件,value是函数,把条件和对应的逻辑组合起来
  1. # 定义各种函数
  2. def is_a():
  3. return 'A'
  4. def is_b():
  5. return 'B'
  6. def is_c():
  7. return 'C'
  8. def is_d():
  9. return 'D'
  10. def is_e():
  11. return 'E'
  12. # 为了方便处理,分数先除以10向下取整,按取整结果选执行逻辑
  13. # 定义switch-case跳转表,这里90分及以上是A,80分及以上是B,70分及以上是C,60分及以上是D
  14. switch_dict = {
  15. 10: is_a,
  16. 9: is_a,
  17. 8: is_b,
  18. 7: is_c,
  19. 6: is_d,
  20. }
  1. 用if-else语句处理能找的到条件的执行逻辑和找不到条件的执行逻辑,也就是实现匹配和默认情况
  1. if score_div_ten in switch_dict.keys():
  2. # 在switch_dict里有对应的逻辑
  3. return switch_dict[score_div_ten]()
  4. else:
  5. # 没在switch_dict里的按默认逻辑处理
  6. return is_e()

全部代码

  1. #!/usr/bin/python
  2. # -*- coding: utf8 -*-
  3. import math
  4. def is_a():
  5. return 'A'
  6. def is_b():
  7. return 'B'
  8. def is_c():
  9. return 'C'
  10. def is_d():
  11. return 'D'
  12. def is_e():
  13. return 'E'
  14. def score_to_af(score):
  15. # 分数除以10以后向下取整,算是属于几十分
  16. score_div_ten = math.floor(score / 10)
  17. # 定义switch-case跳转表,这里90分及以上是A,80分及以上是B,70分及以上是C,60分及以上是D,60分以下都是E(default)
  18. switch_dict = {
  19. 10: is_a,
  20. 9: is_a,
  21. 8: is_b,
  22. 7: is_c,
  23. 6: is_d,
  24. }
  25. if score_div_ten in switch_dict.keys():
  26. return switch_dict[score_div_ten]()
  27. else:
  28. return is_e()
  29. if __name__ == '__main__':
  30. for score in range(0, 101):
  31. print('score:%d, af:%s' % (score, score_to_af(score)))

执行结果

  1. score:0, af:E
  2. score:1, af:E
  3. score:2, af:E
  4. score:3, af:E
  5. score:4, af:E
  6. score:5, af:E
  7. score:6, af:E
  8. score:7, af:E
  9. score:8, af:E
  10. score:9, af:E
  11. score:10, af:E
  12. score:11, af:E
  13. score:12, af:E
  14. score:13, af:E
  15. score:14, af:E
  16. score:15, af:E
  17. score:16, af:E
  18. score:17, af:E
  19. score:18, af:E
  20. score:19, af:E
  21. score:20, af:E
  22. score:21, af:E
  23. score:22, af:E
  24. score:23, af:E
  25. score:24, af:E
  26. score:25, af:E
  27. score:26, af:E
  28. score:27, af:E
  29. score:28, af:E
  30. score:29, af:E
  31. score:30, af:E
  32. score:31, af:E
  33. score:32, af:E
  34. score:33, af:E
  35. score:34, af:E
  36. score:35, af:E
  37. score:36, af:E
  38. score:37, af:E
  39. score:38, af:E
  40. score:39, af:E
  41. score:40, af:E
  42. score:41, af:E
  43. score:42, af:E
  44. score:43, af:E
  45. score:44, af:E
  46. score:45, af:E
  47. score:46, af:E
  48. score:47, af:E
  49. score:48, af:E
  50. score:49, af:E
  51. score:50, af:E
  52. score:51, af:E
  53. score:52, af:E
  54. score:53, af:E
  55. score:54, af:E
  56. score:55, af:E
  57. score:56, af:E
  58. score:57, af:E
  59. score:58, af:E
  60. score:59, af:E
  61. score:60, af:D
  62. score:61, af:D
  63. score:62, af:D
  64. score:63, af:D
  65. score:64, af:D
  66. score:65, af:D
  67. score:66, af:D
  68. score:67, af:D
  69. score:68, af:D
  70. score:69, af:D
  71. score:70, af:C
  72. score:71, af:C
  73. score:72, af:C
  74. score:73, af:C
  75. score:74, af:C
  76. score:75, af:C
  77. score:76, af:C
  78. score:77, af:C
  79. score:78, af:C
  80. score:79, af:C
  81. score:80, af:B
  82. score:81, af:B
  83. score:82, af:B
  84. score:83, af:B
  85. score:84, af:B
  86. score:85, af:B
  87. score:86, af:B
  88. score:87, af:B
  89. score:88, af:B
  90. score:89, af:B
  91. score:90, af:A
  92. score:91, af:A
  93. score:92, af:A
  94. score:93, af:A
  95. score:94, af:A
  96. score:95, af:A
  97. score:96, af:A
  98. score:97, af:A
  99. score:98, af:A
  100. score:99, af:A
  101. score:100, af:A

思路2的思考过程

一段if-elif-else代码

  1. def score_to_af2(score):
  2. # 分数除以10以后向下取整,算是属于几十分
  3. score_div_ten = math.floor(score / 10)
  4. if 9 <= score_div_ten <= 10:
  5. result = 'A'
  6. elif score_div_ten == 8:
  7. result = 'B'
  8. elif score_div_ten == 7:
  9. result = 'C'
  10. elif score_div_ten == 6:
  11. result = 'D'
  12. else:
  13. result = 'E'
  14. return result

条件和执行逻辑

很简单的代码,条件和一行简单的逻辑的对应关系,还是继续抽函数,抽出来每个条件的函数:

  1. # 定义各种函数
  2. def is_a():
  3. return 'A'
  4. def is_b():
  5. return 'B'
  6. def is_c():
  7. return 'C'
  8. def is_d():
  9. return 'D'
  10. def is_e():
  11. return 'E'

然后代码变成:

  1. def score_to_af2(score):
  2. # 分数除以10以后向下取整,算是属于几十分
  3. score_div_ten = math.floor(score / 10)
  4. if 9 <= score_div_ten <= 10:
  5. result = is_a()
  6. elif score_div_ten == 8:
  7. result = is_b()
  8. elif score_div_ten == 7:
  9. result = is_c()
  10. elif score_div_ten == 6:
  11. result = is_d()
  12. else:
  13. result = is_e()
  14. return result

条件和执行逻辑&Key和Value

执行逻辑抽取完成,开始抽条件;因为条件和函数对应的关系就是字典中key和value的关系,所以可以抽成一个key是条件,value是函数的字典

  1. # 定义switch-case跳转表,这里90分及以上是A,80分及以上是B,70分及以上是C,60分及以上是D,60分以下都是E(default)
  2. switch_dict = {
  3. 10: is_a,
  4. 9: is_a,
  5. 8: is_b,
  6. 7: is_c,
  7. 6: is_d,
  8. }

抽完字典开始围绕字典写逻辑,和上面score_to_af的代码一致,以及最后成品代码也是一致,不再赘述。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/1012902
推荐阅读
相关标签
  

闽ICP备14008679号