To be, or not to be: that is the question:
上边这段,出自莎士比亚出《哈姆雷特》第三幕第一场,哈姆雷特王子独白,其中第一句“To be, or not to be”是脍炙人口的名句。名句自然有名译,当然名译也会有很多版本,比如——
朱生豪:生存还是毁灭,这是一个值得考虑的问题;
梁实秋:死后还是存在,还是不存在,——这是问题;
曹未风:生存还是不生存:就是这个问题:
孙大雨:是生存还是消亡,问题的所在;
林同济:存在,还是毁灭,就这问题了。
方平:活着好,还是死了好,这是个难题啊:
卞之琳:活下去还是不活:这是问题。
王佐良:生或死,这就是问题所在。
许渊冲:死还是不死,这是个问题。
裘克安:活着,还是不活了,问题就在这里:
陈国华:是生,还是死,问题就在这里:
又扯远了哈,回来说正题。“To be, or not to be”的本意,以及如何翻译,都是一个选择的问题,在结构化程序中“选择”是一个非常重要的部分,而对于程序设计来说,“选择”以及其所蕴含的逻辑操作模式,是自动化处理的核心。下面就来看看个python如何在一行中实现选择分支。
先看一种好理解的方式。首先要注意的是,由于语句会影响当前空间内的变量,我们必须要保证满足条件以后再执行语句,而不是选择不同语句执行的结果。所以下面的方式是一种可行方案:
>>>(['a' for x in [1] if 1==1],['b' for x in [1] if 1==2]) |
其中1==1和1==2就是if中的判断部分,'a'和'b'就是满足条件时执行的语句。这样,无论你有多少个判断,都可以一个个排列出来去执行。但是这种方式虽然结构很容易理解,但是看上去臃肿的很,而且每次都判断,效率也不高。如果能像c语言的问号表达式一样,才称得上是漂亮的解决方案。不过这里我们先把这个美丽的设想放下,从另一个角度说起。
不像大多数支持结构化程序设计思想的语言,python里没有switch-case结构。如果你对此耿耿于怀的话,相信下面这段手册中关于if语句的语法结构定义一定不陌生:
if_stmt | ::= | "if" expression ":" suite |
( "elif" expression ":" suite )* | ||
["else" ":" suite |
确实,多次使用elif可以模拟出switch-case结构,但是如果你在查阅资料的过程中到这里一游过:https://docs.python.org/2/faq/design.html#why-isn-t-there-a-switch-or-case-statement-in-python ,你对本文开头提出的问题一定是胸有成竹。看名字就知道,前面的链接是python对于不设计switch-case语句的官方解释。里面租了这样的例子:
答案很明显了吧?使用lisi、dict等方式,将分支中的语句包含在子函数定义中,再根据判断变量的值来自动选择使用哪个函数,这样就可以将if甚至switch-case语句完全函数化。看下面的例子:
>>> sel=[lambda x:(x.insert(1,(x.pop(1)*3+1)),x[1])[1],lambda x:(x.insert(1,(x.pop(1)/2)),x[1])[1]] |
这里,我们先将连个不同的函数放在名为sel的list中sel[0]的作用是返回输入list第二个参数乘3加1的值,sel[1]的作用是返回输入list第二个参数的值的一半。“(2%2)==0”这个结构是为了对分支条件进行判断,以决定用哪个函数。由于:
>>> ('a'=='a')==1 |
所以我们可以使用这种简单的方式将逻辑值True、False当作1、0来使用。那么有两个分支的if语句就可以变成以下模式:
[lambda varList:'false statement',lambda varList:'false statement']['test statement'](realVarList) |
现在,我们已经解决了顺序结构、选择结构的编写方法,下一次就轮到最令人纠结的循环结构了。