Re: [讨论] Python 3.10将加入Switch-Case语句

楼主: Muscovy (三分熟的闹钟)   2021-03-27 16:09:33
※ 引述《ohmylove347 (米特巴尔)》之铭言:
: https://reurl.cc/8yzA24
: 上面说2006年 PEP 3103就建议实施switch-case语句。
: 但是,在PyCon 2007上的一项民意调查未获得对该功能的支持后,
: Python开发人员将其删除。
:
: 没有使用Python不知道生态系如何
: Google App上看到的文章
: 不知道各位大大对Switch加入有什么看法
:
: 推 Muscovy: for/while 比 if-else 常出现无误, 大概 10:1 的比例. XD
: 推 TAMSHUI: 不知M大能否举例完全不用if-else呢?Google了一下还是没
: → TAMSHUI: 什么想法@@
: 推 Muscovy: 不会到完全不写 if 的程度啦,等一下我来整理一篇
我的工作环境很杂, 从 matlab 到 C 与他的亲朋好友(java 也算. :D)
反正猴子用 C, 有钱的猴子用 matlab, 没钱的猴子像我就用 python.
但是大概都会双栖...
我来举个例子...
譬如你有一组数字, 数量不多不少, 大约 10,000 个左右.
然后要处理它, 先叫他 eigen_spectrum, 或者简称 eig 好了.
当 eigen_spectrum >= 100,000,000 的时候要做一堆事.
介于 [10, 100,000,000) 的时候又一堆事.
介于 (0, 10) 的时候又一堆.
刚好等于 0 的时候需要处理特殊事件.
然后小于 0 的话要检查有没有奇怪的现象, 标注一些警示.
这些事情的执行细节通通都不太一样, 然后要怎么做?
用 C 的话, 大概 if-else/if-else/if-...-else 之外就没招了.
所以 python by C programmer 会变这样:
for s in eigen_spectrum:
if s >= 1e8:
pass # 这里写一大坨, 顶多写个函数处理.
elif s >= 10 and s < 1e8:
pass # 这里再一坨, 或者写个跟上面不一样函数.
elif s > 0 and s < 10:
pass # 再一坨, 或者再一个跟上面都不同的函数.
elif s == 0:
pass # 嗯, 你知道的, 继续.
elif s < 0:
pass # 嗯......写就对了.
else:
raise ValueError("Should not happen.")
最后你会得到一堆只用一次的函数, 或者一大串超长程式码.
但是 python programmer 呢, 会这样写:
for s in eig[eig > 1e8]:
pass # 写写写, 也是一大坨.
for s in eig[np.logical_and(eig > 10, eig < 1e8)]:
pass # 继续写写写, 也是一坨.
for s in eig[np.logical_and(eig > 0, eig < 10)]:
pass # 再写, 继续就对了.
if np.any(eig == 0):
pass # 惊醒! 想一下遇上 0 的时候要做什么.
for s in eig[eig < 0]:
pass # 再写再写, 反正就是接龙.
很有趣的结构吧? 你还是会变出一段超长程式码.
再加上明明一个循环可以搞定的事, 硬要拆成四个.
还补了一个莫名其妙, 不太对称的 if.
但事实上这种写法比较好维护, 因为这个结构更近似数学的模型.
可以往前翻到我上面的文字叙述, 比看看两种写法就知道了.
这个数学模型很简单, 然而不同的写法就已经有风格上的区分.
稍微复杂一点的数学模型, 用 if-elif-else 就更难重建.
譬如这个 eigen_spectrum 会有一组伴随的 eigen_states 要处理.
用 if-else 硬爬会爬出一堆脑袋打结的程式码, 因为很不像数学.
然后结构里面的 if 其实是用来做 s == 0, exception handle.
而且这也是我最常遭遇的情境: 用 if + raise 来表示异常状况.
其他时候, 我一下子想不太到写 if statement 的情况.
因为翻到的程式码几乎都是:
if np.count_nonzero(np.abs(s) < 1e-8) > 2:
raise ValueError('Too many singularities.')
这一类的东西, 它就是有个 raise.
: → as30385438: 不用if就是用loop、dict的key放condition或一些DP手法
: → as30385438: 写python的常常追求所谓的pythonic,不过我自己是觉得
: → as30385438: simple is best,最直觉的写法通常就是最好的
从 stackoverflow 容易学到的毛病就是把 one-liner 当成 pythonian.
养成这种习惯的程式员有够难矫正.
作者: bazoo (surfers'paradise)   2021-03-27 16:19:00
请问这是使用 numpy 吗?for 循环的范例那边
楼主: Muscovy (三分熟的闹钟)   2021-03-27 16:21:00
是. python 内建的也有类似的写法, 但 numpy 比较简洁.
作者: neo5277 (I am an agent of chaos)   2021-03-27 18:24:00
好像是满好玩的 关心值 不知道会不会比较有效果
作者: Murasaki0110 (麦当劳欢乐送)   2021-03-27 18:33:00
变成5次for好在哪里
作者: alihue (wanda wanda)   2021-03-27 18:51:00
第二种其实 eig 会被 scan 五次?效能不是比较差吗
作者: handsomeLin (DoGLin)   2021-03-27 18:54:00
我是python progammer但是我用if else 不会用5n循环
作者: jack82822005 (小郭郭)   2021-03-27 19:11:00
看起来似乎比较好懂,但效能比较差的样子
作者: alihue (wanda wanda)   2021-03-27 19:29:00
其实第二个可读性没比第一个好 后人还会觉得干嘛不用一个循环你若要raise ex,第二种更难读出何时会 raise ex然后如果你 pass 里面资料是不能被重复处理的,在第二种case 若条件有 overlap 会出 bug
作者: Celinealone   2021-03-27 20:31:00
不太懂为什么第二个会比较好维护? Python也可以用第一种写法不是吗?
作者: WunoW (WunoW)   2021-03-27 20:35:00
明明就if-else比较好维护吧...
作者: drajan (EasoN)   2021-03-27 20:40:00
“pythonic”
作者: mirror0227 (镜子)   2021-03-27 20:46:00
我也选 if else
作者: geniusturtle (小龟)   2021-03-27 20:48:00
觉得第二种不好读
作者: noahleft (NoahLeft)   2021-03-27 21:04:00
第二种以维护角度比较容易, 第一种当条件混入各种可能后会很难知道什么时候会跑到哪个条件只要考虑到有情形是多个条件都能成立时,第一种写法就是看执行顺序,而第二种写法会变成喂进来的资料都是符合条见的
作者: WunoW (WunoW)   2021-03-27 21:10:00
多条件你就用多个if就好不用else了 = =
作者: noahleft (NoahLeft)   2021-03-27 21:22:00
补充一下 多条件指可能你的condition并非完全互斥
作者: hsnuyi (羊咩咩~)   2021-03-27 21:51:00
又是一个不考虑CPU如何branch的人
作者: WunoW (WunoW)   2021-03-27 21:53:00
NO 你先if排除不符合的条件更直观也有更好的效能我知道你是想遵循单一职责原则,但这不是定律一个循环做多个判断没有不行 你判断式提取为函式就好
作者: alihue (wanda wanda)   2021-03-27 22:02:00
楼上说到一个重点...if的位置在某些情况可以大幅改善效能
作者: WunoW (WunoW)   2021-03-27 22:03:00
你去看pandas的源码吧 一个for loop里面包山包海的code一堆
作者: alihue (wanda wanda)   2021-03-27 22:04:00
例如在循环的一开始就筛掉大部分 case 并 continue
作者: MoonCode (MoonCode)   2021-03-27 22:09:00
先写的简单好懂比效能重要 推推
作者: jack0204 (Jarbar王朝)   2021-03-27 22:22:00
楼上说的这叫early return,写可读性高的程式常用到
作者: enthos (影斯作业系统)   2021-03-27 23:16:00
作者: shooter555 (shooter)   2021-03-29 12:38:00
for in 后面的条件不会先被展开吗 这样不是比较慢?然后第二种写写一大长串不是很难看吗 第一种虽然一堆一次性的func 但拿来命名可以清楚看出他是要干么的
作者: s0914714 (YA)   2021-03-30 17:14:00
以这个例子而言 的确1的写法不会比较差 就是分区而已但复杂情况2的维护性会高不少
作者: red0210 (My Name Is Red)   2021-04-04 15:42:00
in 后面计算量通常不大(跟里面那堆比),拿去profiling就知道了

Links booklink

Contact Us: admin [ a t ] ucptt.com