最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python中 ? : 三元表達(dá)式的使用介紹

 更新時(shí)間:2013年10月09日 22:39:06   作者:  
剛剛學(xué)python的時(shí)候,時(shí)常糾結(jié)于python中沒有C語言中 ? : 的實(shí)現(xiàn),今天終于發(fā)現(xiàn)了兩種python的實(shí)現(xiàn)方式

(1) variable = a if exper else b
(2)variable = (exper and [b] or [c])[0]
(2) variable = exper and b or c

上面三種用法都可以達(dá)到目的,類似C語言中 variable = exper ? b : c;即:如果exper表達(dá)式的值為true則variable = b,否則,variable = c

例如:

復(fù)制代碼 代碼如下:

a,b=1,2
max = (a if a > b else b)
max = (a > b and [a] or [b])[0] #list
max = (a > b and a or b)


現(xiàn)在大部分高級(jí)語言都支持“?”這個(gè)三元運(yùn)算符(ternary operator),它對(duì)應(yīng)的表達(dá)式如下:condition ? value if true : value if false。很奇怪的是,這么常用的運(yùn)算符python居然不支持!誠(chéng)然,我們可以通過if-else語句表達(dá),但是本來一行代碼可以完成的非要多行,明顯不夠簡(jiǎn)潔。沒關(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為假,那么就沒必要看字符串"True"了(短路效應(yīng)),直接返回"False"。

不難看出,三元運(yùn)算在python中事實(shí)上可以通過借用布爾求值表達(dá)。然后,有時(shí)會(huì)有點(diǎn)小問題。舉個(gè)例子,char *ret = x ? "" or "VAL"。根據(jù)前面的例子,我們很自然想到在python里應(yīng)該這樣寫,ret = x and "" or "VAL"。錯(cuò)了!不管x的布爾求值是真還是假,ret得到的總是"VAL"。奇怪么?不奇怪,因?yàn)樵趐ython中對(duì)空字符串的布爾求值為false,這樣x and ""永遠(yuǎn)都是false,所以ret得到的自然總是"VAL"了。解決這個(gè)問題有兩種辦法,第一種,也是我喜歡的一種,就是寫成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í)寫成ret=x and [val1] or [val2],然后取ret[0]作為結(jié)果了。因?yàn)檫@行語句所表達(dá)的不是“當(dāng)x為真返回val1,否則返回val2”,而是“當(dāng)x為真并且val1為真返回val2,否則返回val2”。

討論二:大家都知道python里有l(wèi)ist和tuple,前面這行代碼ret=x and [""] or ["VAL"]我們就是通過list解決,有的人可能偏愛tuple,于是就會(huì)這樣寫ret=x and ("") or ("VAL")。錯(cuò)了!這里ret[0]永遠(yuǎn)都是空字符串(在2.5上測(cè)試)。這是我比較faint的一點(diǎn),為啥[""]為真而("")為假呢?

最后,附上python對(duì)典型數(shù)值的布爾求值結(jié)果,這對(duì)我們書寫三元運(yùn)算的等價(jià)語句很有用。

輸入 布爾求值
1,-1,[“”] True
0, “”, None, [], (), {}, (“”) False

python 三元表達(dá)式

之前學(xué)習(xí)的Python提到了對(duì)于類似C語言的三元條件表達(dá)式condition ? true_part : false_part,雖然Python沒有三目運(yùn)算符(?:),但也有類似的替代方案,那就是true_part if condition else false_part。

復(fù)制代碼 代碼如下:

>>> 1 if True else 0
1
>>> 1 if False else 0
0
>>> "Fire" if True else "Water"
'Fire'
>>> "Fire" if False else "Water"
'Water'

在編程中我也一直這么用了,直到有一天發(fā)現(xiàn)了一個(gè)有趣的技巧,那就是and-or技巧,利用條件判斷的優(yōu)先特性來實(shí)現(xiàn)三元條件判斷,比如P∧Q,在Python中如果P為假,那么Python將不會(huì)繼續(xù)執(zhí)行Q,而直接判定整個(gè)表達(dá)式為假(P值),當(dāng)然如果P為真,那就還要繼續(xù)執(zhí)行Q來決定整個(gè)表達(dá)式值;同樣的P∨Q,如果P為真,那么就不會(huì)繼續(xù)執(zhí)行Q了…

其實(shí)很多編程語言在邏輯判斷中都應(yīng)用了這套機(jī)制,目前我接觸下來的貌似VB/VBScript可能不是這么做的。有了這套機(jī)制除了在if判斷中提高效率外,我們還可以額外發(fā)掘一些有趣的功能,比如下面的PHP代碼:

復(fù)制代碼 代碼如下:

$conn = @mysql_connect(...) or die("Failed")

如果mysql_connect成功的話將會(huì)返回resource資源句柄,如果失敗的話將會(huì)返回False,等等,后面還有個(gè)or,也就是失敗的話還將會(huì)繼續(xù)執(zhí)行or后面的die語句,于是輸出了錯(cuò)誤信息并終止后續(xù)代碼的執(zhí)行。

再如下面的JavaScript代碼:

復(fù)制代碼 代碼如下:

function getEvent(e) {
    e = e || window.event;
    return e;
}

這段代碼獲取的是event,假如沒有給getEvent傳入值(即e為undefined),或者e為NULL(兩者在JavaScript條件中均代表False),e = e || window.event表達(dá)式將會(huì)把window.event賦值給e,否則e為Object對(duì)象,原表達(dá)式會(huì)蛻化為e = e賦值,也就是沒有改變什么。

好了,扯了這么多,稍稍有些偏題了,下面繼續(xù)聊Python的and-or技巧,可以這么說,這個(gè)技巧也是利用了邏輯判斷的特殊性,貌似在真正的三元表達(dá)式if else沒有出來的時(shí)候其就一直在扮演三元表達(dá)式的角色,其原型是condition and true_part or false_part,下面舉幾個(gè)例子:

復(fù)制代碼 代碼如下:

>>> True and 1 or 0
1
>>> False and 1 or 0
0
>>> True and "Fire" or "Water"
'Fire'
>>> False and "Fire" or "Water"
'Water'

但是值得注意的是雖然表面看上去能夠正常工作,其實(shí)還潛藏有不可知的風(fēng)險(xiǎn),若我們的true_part本身就是個(gè)被Python認(rèn)定為False的值,這個(gè)技巧就不可用了,我們知道空字符串就是這種情況。

復(fù)制代碼 代碼如下:

>>> True and "" or "Water"
'Water'

上面的表達(dá)式其實(shí)我們期望返回空字串的,如何解決呢,我在Dive Into Python中找到了解決方案:那就是利用列表特性,因?yàn)榘兆址牧斜砥浔磉_(dá)式值仍然為True,所以我們可以用列表先包裝一下,然后等表達(dá)式判斷完畢后在解包:

復(fù)制代碼 代碼如下:

>>> a = ""
>>> b = "Water"
>>> (True and [a] or [b])[0]
''

當(dāng)然為了避免出錯(cuò),我們可以將其包裝為函數(shù):

復(fù)制代碼 代碼如下:

def iif(condition, true_part, false_part):
    return (condition and [true_part] or [false_part])[0]

現(xiàn)在Python已經(jīng)在語言特性中加入三元條件表達(dá)式的支持了,那就是文章一開始介紹的if else寫法,所以為了妥善起見,對(duì)于三元判斷還是用新的if else特性吧,其實(shí)Python官方對(duì)于加入三元表達(dá)式語法也是討論了很久的,可以參考《PEP 308 — Conditional Expressions》。

相關(guān)文章

  • Pandas進(jìn)行數(shù)據(jù)編碼的十種方式總結(jié)

    Pandas進(jìn)行數(shù)據(jù)編碼的十種方式總結(jié)

    在機(jī)器學(xué)習(xí)中,很多算法都需要我們對(duì)分類特征進(jìn)行轉(zhuǎn)換(編碼),即根據(jù)某一列的值,新增(修改)一列。本文為大家總結(jié)了Pandas中十種數(shù)據(jù)編碼的方式,需要的可以參考一下
    2022-04-04
  • Python中range、np.arange和np.linspace的區(qū)別

    Python中range、np.arange和np.linspace的區(qū)別

    本文主要介紹了Python中range、np.arange和np.linspace的區(qū)別,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 用python實(shí)現(xiàn)百度翻譯的示例代碼

    用python實(shí)現(xiàn)百度翻譯的示例代碼

    這篇文章主要介紹了用python實(shí)現(xiàn)百度翻譯的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • 關(guān)于python中的setup.py

    關(guān)于python中的setup.py

    distutils?的精髓在于編寫?setup.py,它是模塊分發(fā)與安裝的指導(dǎo)文件,那么如何編寫?setup.py?呢?這里面的內(nèi)容非常多,我會(huì)在本文給大家詳細(xì)講解,對(duì)python?setup.py相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-08-08
  • python 使用shutil復(fù)制圖片的例子

    python 使用shutil復(fù)制圖片的例子

    今天小編就為大家分享一篇python 使用shutil復(fù)制圖片的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • 使用python繪制愛心效果代碼實(shí)例

    使用python繪制愛心效果代碼實(shí)例

    本文介紹了如何使用Python的Turtle模塊繪制一個(gè)紅色的愛心圖形,示例代碼通過定義draw_love函數(shù),利用Turtle的移動(dòng)和轉(zhuǎn)向功能,實(shí)現(xiàn)了愛心輪廓的繪制,并填充紅色,這種方法適用于簡(jiǎn)單的圖形繪制,并可視化展示結(jié)果,需要的朋友可以參考下
    2024-09-09
  • Python實(shí)戰(zhàn)之外星人入侵游戲示例代碼

    Python實(shí)戰(zhàn)之外星人入侵游戲示例代碼

    這篇文章主要介紹了利用Python編寫的外星人入侵游戲的示例代碼,文中的代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定的幫助,感興趣的可以學(xué)習(xí)一下
    2022-01-01
  • python使用pika庫(kù)調(diào)用rabbitmq參數(shù)使用詳情

    python使用pika庫(kù)調(diào)用rabbitmq參數(shù)使用詳情

    這篇文章主要介紹了python使用pika庫(kù)調(diào)用rabbitmq參數(shù)使用詳情,文章通過展開文章主題分享了三種方式,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • Python中序列的修改、散列與切片詳解

    Python中序列的修改、散列與切片詳解

    在Python中,最基本的數(shù)據(jù)結(jié)構(gòu)是序列(sequence)。下面這篇文章主要給大家介紹了關(guān)于Python中序列的修改、散列與切片的相關(guān)資料文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考,下面來一起看看吧。
    2017-08-08
  • pandas如何使用列表和字典創(chuàng)建?Series

    pandas如何使用列表和字典創(chuàng)建?Series

    這篇文章主要介紹了pandas如何使用列表和字典創(chuàng)建?Series,pandas 是基于NumPy的一種工具,該工具是為解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的,下文我們就來看看文章是怎樣介紹pandas,需要的朋友也可以參考一下
    2021-12-12

最新評(píng)論

定结县| 鸡泽县| 荔波县| 那曲县| 福贡县| 宁河县| 乐东| 曲靖市| 武穴市| 铜山县| 彩票| 昌平区| 新巴尔虎左旗| 华阴市| 盘锦市| 旺苍县| 两当县| 蒲江县| 合江县| 宾阳县| 龙南县| 昭平县| 延安市| 罗山县| 潼关县| 霍山县| 庄河市| 昭通市| 莎车县| 绥阳县| 广丰县| 勐海县| 图们市| 赤城县| 淮阳县| 潍坊市| 噶尔县| 阳春市| 台山市| 廊坊市| 东港市|