python中 ? : 三元表达式的使用介绍
(1) variable = a if exper else b
(2)variable = (exper and [b] or [c])[0]
(2) variable = exper and b or c
上面三种用法都可以达到目的,类似C语言中 variable = exper ? b : c;即:如果exper表达式的值为true则variable = b,否则,variable = c
例如:
代码如下:
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)
现在大部分高级语言都支持“?”这个三元运算符(ternary operator),它对应的表达式如下:condition ? value if true : value if false。很奇怪的是,这么常用的运算符python居然不支持!诚然,我们可以通过if-else语句表达,但是本来一行代码可以完成的非要多行,明显不够简洁。没关系,在python里其实还是有对应的表达方式的。
举个例子:char *ret = (x!=0) ? "True" : "False"这行代码对应的python形式就是ret = (x and "True") or "False"(很简单吧,事实上括号可以去掉)。运行时,python虚拟机会对赋值符右边的布尔表达式(注意这里并非三元表达式)求值,返回值是最后一个被分析到的值。为什么是“最后一个被分析到的”而不是表达式中“最后一个”呢?因为布尔表达式有一个短路效应,比如a or b,如果a为真那么就不会分析b了。嗯,估计现在大家差不多明白了这行python代码的原理了。如果x为真,由于字符串“True”也为真,于是返回"True",反之,x为假,那么就没必要看字符串"True"了(短路效应),直接返回"False"。
不难看出,三元运算在python中事实上可以通过借用布尔求值表达。然后,有时会有点小问题。举个例子,char *ret = x ? "" or "VAL"。根据前面的例子,我们很自然想到在python里应该这样写,ret = x and "" or "VAL"。错了!不管x的布尔求值是真还是假,ret得到的总是"VAL"。奇怪么?不奇怪,因为在python中对空字符串的布尔求值为false,这样x and ""永远都是false,所以ret得到的自然总是"VAL"了。解决这个问题有两种办法,第一种,也是我喜欢的一种,就是写成ret = not x and "VAL" or ""。第二种,麻烦一点ret=x and [""] or ["VAL"],然后每次取ret[0]作为返回值,这是因为[""]在布尔求值时值为true。
讨论一:第一种方法代码明显要简洁,效率也高,那么还有必要使用第二种么?当然,第一种办法有局限性,只有当我们非常明确其中一个值布尔求值时不可能为false时才能使用。在我们的示例中,由于"VAL"肯定返回true所以可以使用。如果是两个变量呢,像这样ret=x and val1 or val2,你就只能老老实实写成ret=x and [val1] or [val2],然后取ret[0]作为结果了。因为这行语句所表达的不是“当x为真返回val1,否则返回val2”,而是“当x为真并且val1为真返回val2,否则返回val2”。
讨论二:大家都知道python里有list和tuple,前面这行代码ret=x and [""] or ["VAL"]我们就是通过list解决,有的人可能偏爱tuple,于是就会这样写ret=x and ("") or ("VAL")。错了!这里ret[0]永远都是空字符串(在2.5上测试)。这是我比较faint的一点,为啥[""]为真而("")为假呢?
最后,附上python对典型数值的布尔求值结果,这对我们书写三元运算的等价语句很有用。
输入 | 布尔求值 |
代码如下:
在编程中我也一直这么用了,直到有一天发现了一个有趣的技巧,那就是and-or技巧,利用条件判断的优先特性来实现三元条件判断,比如P∧Q,在Python中如果P为假,那么Python将不会继续执行Q,而直接判定整个表达式为假(P值),当然如果P为真,那就还要继续执行Q来决定整个表达式值;同样的P∨Q,如果P为真,那么就不会继续执行Q了… 其实很多编程语言在逻辑判断中都应用了这套机制,目前我接触下来的貌似VB/VBScript可能不是这么做的。有了这套机制除了在if判断中提高效率外,我们还可以额外发掘一些有趣的功能,比如下面的PHP代码: 代码如下:
如果mysql_connect成功的话将会返回resource资源句柄,如果失败的话将会返回False,等等,后面还有个or,也就是失败的话还将会继续执行or后面的die语句,于是输出了错误信息并终止后续代码的执行。 再如下面的JavaScript代码: 代码如下:
这段代码获取的是event,假如没有给getEvent传入值(即e为undefined),或者e为NULL(两者在JavaScript条件中均代表False),e = e || window.event表达式将会把window.event赋值给e,否则e为Object对象,原表达式会蜕化为e = e赋值,也就是没有改变什么。 好了,扯了这么多,稍稍有些偏题了,下面继续聊Python的and-or技巧,可以这么说,这个技巧也是利用了逻辑判断的特殊性,貌似在真正的三元表达式if else没有出来的时候其就一直在扮演三元表达式的角色,其原型是condition and true_part or false_part,下面举几个例子: 代码如下:
但是值得注意的是虽然表面看上去能够正常工作,其实还潜藏有不可知的风险,若我们的true_part本身就是个被Python认定为False的值,这个技巧就不可用了,我们知道空字符串就是这种情况。 代码如下:
上面的表达式其实我们期望返回空字串的,如何解决呢,我在Dive Into Python中找到了解决方案:那就是利用列表特性,因为包含空字符串的列表其表达式值仍然为True,所以我们可以用列表先包装一下,然后等表达式判断完毕后在解包: 代码如下:
当然为了避免出错,我们可以将其包装为函数: 代码如下:
现在Python已经在语言特性中加入三元条件表达式的支持了,那就是文章一开始介绍的if else写法,所以为了妥善起见,对于三元判断还是用新的if else特性吧,其实Python官方对于加入三元表达式语法也是讨论了很久的,可以参考《PEP 308 — Conditional Expressions》。 |

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











このチュートリアルでは、Pythonを使用してZIPFの法則の統計的概念を処理する方法を示し、法律の処理時にPythonの読み取りおよび並べ替えの効率性を示します。 ZIPF分布という用語が何を意味するのか疑問に思うかもしれません。この用語を理解するには、まずZIPFの法律を定義する必要があります。心配しないでください、私は指示を簡素化しようとします。 ZIPFの法則 ZIPFの法則は単に意味します。大きな自然言語のコーパスでは、最も頻繁に発生する単語は、2番目の頻繁な単語のほぼ2倍の頻度で表示されます。 例を見てみましょう。アメリカ英語の茶色のコーパスを見ると、最も頻繁な言葉は「thであることに気付くでしょう。

この記事では、Pythonライブラリである美しいスープを使用してHTMLを解析する方法について説明します。 find()、find_all()、select()、およびget_text()などの一般的な方法は、データ抽出、多様なHTML構造とエラーの処理、および代替案(SEL

この記事では、深い学習のためにTensorflowとPytorchを比較しています。 関連する手順、データの準備、モデルの構築、トレーニング、評価、展開について詳しく説明しています。 特に計算グラップに関して、フレームワーク間の重要な違い

Pythonオブジェクトのシリアル化と脱介入は、非自明のプログラムの重要な側面です。 Pythonファイルに何かを保存すると、構成ファイルを読み取る場合、またはHTTPリクエストに応答する場合、オブジェクトシリアル化と脱滑り化を行います。 ある意味では、シリアル化と脱派化は、世界で最も退屈なものです。これらすべての形式とプロトコルを気にするのは誰ですか? Pythonオブジェクトを維持またはストリーミングし、後で完全に取得したいと考えています。 これは、概念レベルで世界を見るのに最適な方法です。ただし、実用的なレベルでは、選択したシリアル化スキーム、形式、またはプロトコルは、プログラムの速度、セキュリティ、メンテナンスの自由、およびその他の側面を決定する場合があります。

Pythonの統計モジュールは、強力なデータ統計分析機能を提供して、生物統計やビジネス分析などのデータの全体的な特性を迅速に理解できるようにします。データポイントを1つずつ見る代わりに、平均や分散などの統計を見て、無視される可能性のある元のデータの傾向と機能を発見し、大きなデータセットをより簡単かつ効果的に比較してください。 このチュートリアルでは、平均を計算し、データセットの分散の程度を測定する方法を説明します。特に明記しない限り、このモジュールのすべての関数は、単に平均を合計するのではなく、平均()関数の計算をサポートします。 浮動小数点数も使用できます。 ランダムをインポートします インポート統計 fractiから

このチュートリアルでは、システム全体の観点からPythonのエラー条件を処理する方法を学びます。エラー処理は設計の重要な側面であり、エンドユーザーまでずっと(ハードウェア)が最も低いレベル(場合によってはハードウェア)を超えます。 yの場合

この記事では、numpy、pandas、matplotlib、scikit-learn、tensorflow、django、flask、and requestsなどの人気のあるPythonライブラリについて説明し、科学的コンピューティング、データ分析、視覚化、機械学習、Web開発、Hの使用について説明します。

このチュートリアルは、単純なツリーナビゲーションを超えたDOM操作に焦点を当てた、美しいスープの以前の紹介に基づいています。 HTML構造を変更するための効率的な検索方法と技術を探ります。 1つの一般的なDOM検索方法はExです
