Python語(yǔ)言技巧之三元運(yùn)算符使用介紹
python不支持C/C++中的三元操作符 ?:,替代的方法是 ...if... else...
舉例,用下面的語(yǔ)法實(shí)現(xiàn)求三個(gè)數(shù)的最小值。
nD1 if nD1 < ( nD2 if nD2<nD3 else nD3) else (nD2 if nD2 < nD3 else nD3)
python三元運(yùn)算符的正確方法
因?yàn)橄轮芤胮hp寫(xiě)項(xiàng)目,所以周末在家里重新看php的語(yǔ)法,看到三元描述符,突然想起來(lái)python是沒(méi)有三元描述符的,印象中依稀記得有模擬的實(shí)現(xiàn),于是上網(wǎng)上搜了一下。
(對(duì)應(yīng)C語(yǔ)言的 X ? V1:V2)
其中一種是:
(X and V1) or V2
正常情況下是不會(huì)有錯(cuò)誤的,但是文章中也提到了,當(dāng)V1=""時(shí),就會(huì)有問(wèn)題
比如
print (True and '') or 'V'
print (False and '') or 'V'
輸出永遠(yuǎn)都是: V
完美的解決方案是在《python核心編程中提到的》:
V1 if X else V2
原文如下:
如果你來(lái)自 C/C++ 或者是 Java 世界, 那么你很難忽略的一個(gè)事實(shí)就是 Python 在很長(zhǎng)的一
段時(shí)間里沒(méi)有條件表達(dá)式(C ? X : Y), 或稱(chēng)三元運(yùn)算符. ( C 是條件表達(dá)式; X 是 C 為 True 時(shí)
的結(jié)果, Y 是 C 為 False 時(shí)的結(jié)果) 貴鐸·范·羅薩姆一直拒絕加入這樣的功能, 因?yàn)樗J(rèn)為應(yīng)
該保持代碼簡(jiǎn)單, 讓程序員不輕易出錯(cuò). 不過(guò)在十年多后, 他放棄了, 主要是因?yàn)槿藗冊(cè)囍?
and 和 or 來(lái)模擬它, 但大多都是錯(cuò)誤的. 根據(jù) FAQ , 正確的方法(并不唯一)是
(C and [X] or [Y])[0] . 唯一的問(wèn)題是社區(qū)不同意這樣的語(yǔ)法. (你可以看一看 PEP 308, 其
中有不同的方案.) 對(duì)于Python 的這一問(wèn)題,人們表達(dá)了極大的訴求.
貴鐸·范·羅薩姆最終選擇了一個(gè)最被看好(也是他最喜歡)的方案, 然后把它運(yùn)用于標(biāo)準(zhǔn)庫(kù)中
的一些模塊. 根據(jù) PEP , "這個(gè)評(píng)審?fù)ㄟ^(guò)考察大量現(xiàn)實(shí)世界的案例, 包含不同的應(yīng)用, 以及由不同
程序員完成的代碼." 最后 Python 2.5 集成的語(yǔ)法確定為: X if C else Y .
如上文所說(shuō),該語(yǔ)法在python2.5才被加入,但是因?yàn)槠綍r(shí)也不會(huì)用到2.4及以前的版本,所以也就夠用了~
現(xiàn)在大部分高級(jí)語(yǔ)言都支持“?”這個(gè)三元運(yùn)算符(ternary operator),它對(duì)應(yīng)的表達(dá)式如下:condition ? value if true : value if false。很奇怪的是,這么常用的運(yùn)算符python居然不支持!誠(chéng)然,我們可以通過(guò)if-else語(yǔ)句表達(dá),但是本來(lái)一行代碼可以完成的非要多行,明顯不夠簡(jiǎn)潔。沒(méi)關(guān)系,在python里其實(shí)還是有對(duì)應(yīng)的表達(dá)方式的。
舉個(gè)例子:char *ret = (x!=0) ? "True" : "False"這行代碼對(duì)應(yīng)的python形式就是ret = (x and "True") or "False"(很簡(jiǎn)單吧,事實(shí)上括號(hào)可以去掉)。運(yùn)行時(shí),python虛擬機(jī)會(huì)對(duì)賦值符右邊的布爾表達(dá)式(注意這里并非三元表達(dá)式)求值,返回值是最后一個(gè)被分析到的值。為什么是“最后一個(gè)被分析到的”而不是表達(dá)式中“最后一個(gè)”呢?因?yàn)椴紶柋磉_(dá)式有一個(gè)短路效應(yīng),比如a or b,如果a為真那么就不會(huì)分析b了。嗯,估計(jì)現(xiàn)在大家差不多明白了這行python代碼的原理了。如果x為真,由于字符串“True”也為真,于是返回"True",反之,x為假,那么就沒(méi)必要看字符串"True"了(短路效應(yīng)),直接返回"False"。
不難看出,三元運(yùn)算在python中事實(shí)上可以通過(guò)借用布爾求值表達(dá)。然后,有時(shí)會(huì)有點(diǎn)小問(wèn)題。舉個(gè)例子,char *ret = x ? "" or "VAL"。根據(jù)前面的例子,我們很自然想到在python里應(yīng)該這樣寫(xiě),ret = x and "" or "VAL"。錯(cuò)了!不管x的布爾求值是真還是假,ret得到的總是"VAL"。奇怪么?不奇怪,因?yàn)樵趐ython中對(duì)空字符串的布爾求值為false,這樣x and ""永遠(yuǎn)都是false,所以ret得到的自然總是"VAL"了。解決這個(gè)問(wèn)題有兩種辦法,第一種,也是我喜歡的一種,就是寫(xiě)成ret = not x and "VAL" or ""。第二種,麻煩一點(diǎn)ret=x and [""] or ["VAL"],然后每次取ret[0]作為返回值,這是因?yàn)閇""]在布爾求值時(shí)值為true。
討論一:第一種方法代碼明顯要簡(jiǎn)潔,效率也高,那么還有必要使用第二種么?當(dāng)然,第一種辦法有局限性,只有當(dāng)我們非常明確其中一個(gè)值布爾求值時(shí)不可能為false時(shí)才能使用。在我們的示例中,由于"VAL"肯定返回true所以可以使用。如果是兩個(gè)變量呢,像這樣ret=x and val1 or val2,你就只能老老實(shí)實(shí)寫(xiě)成ret=x and [val1] or [val2],然后取ret[0]作為結(jié)果了。因?yàn)檫@行語(yǔ)句所表達(dá)的不是“當(dāng)x為真返回val1,否則返回val2”,而是“當(dāng)x為真并且val1為真返回val2,否則返回val2”。
討論二:大家都知道python里有l(wèi)ist和tuple,前面這行代碼ret=x and [""] or ["VAL"]我們就是通過(guò)list解決,有的人可能偏愛(ài)tuple,于是就會(huì)這樣寫(xiě)ret=x and ("") or ("VAL")。錯(cuò)了!這里ret[0]永遠(yuǎn)都是空字符串(在2.5上測(cè)試)。這是我比較faint的一點(diǎn),為啥[""]為真而("")為假呢?
最后,附上python對(duì)典型數(shù)值的布爾求值結(jié)果,這對(duì)我們書(shū)寫(xiě)三元運(yùn)算的等價(jià)語(yǔ)句很有用。
| 輸入 | 布爾求值 |
| 1,-1,[“”] | True |
| 0, “”, None, [], (), {}, (“”) | False |
相關(guān)文章
Python內(nèi)置函數(shù)及功能簡(jiǎn)介匯總
這篇文章主要介紹了Python內(nèi)置函數(shù)及功能簡(jiǎn)介匯總,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5多線(xiàn)程中信號(hào)與槽的詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5多線(xiàn)程中信號(hào)與槽的詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-03-03
Python繪制圣誕樹(shù)+落葉+雪花+背景音樂(lè)+浪漫彈窗?五合一版圣誕樹(shù)
馬上不就到圣誕節(jié)了嘛,我看到朋友圈里很多小伙伴再紛紛炫耀自己收到的專(zhuān)屬圣誕樹(shù),今天小編給大家介紹的是通過(guò)Python繪制的五合一版圣誕樹(shù):圣誕樹(shù)+落葉+雪花+背景音樂(lè)+浪漫彈窗。感興趣的小伙伴快來(lái)學(xué)習(xí)一下吧2021-12-12
python圖形工具turtle繪制國(guó)際象棋棋盤(pán)
這篇文章主要為大家詳細(xì)介紹了python圖形工具turtle繪制國(guó)際象棋棋盤(pán),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
python多線(xiàn)程semaphore實(shí)現(xiàn)線(xiàn)程數(shù)控制的示例
這篇文章主要介紹了python多線(xiàn)程semaphore實(shí)現(xiàn)線(xiàn)程數(shù)控制的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Windows和Linux下Python輸出彩色文字的方法教程
這篇文章主要介紹了在Windows和Linux中Python輸出彩色文字的方法,通過(guò)設(shè)置彩色文字給大家更醒目的效果,文中給出了詳細(xì)的介紹和示例代碼,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-05-05
Flask框架請(qǐng)求鉤子與request請(qǐng)求對(duì)象用法實(shí)例分析
這篇文章主要介紹了Flask框架請(qǐng)求鉤子與request請(qǐng)求對(duì)象用法,結(jié)合實(shí)例形式詳細(xì)分析了Flask框架請(qǐng)求鉤子與request請(qǐng)求對(duì)象相關(guān)原理、用法及操作注意事項(xiàng),需要的朋友可以參考下2019-11-11

