11

このメソッドは、単語文字の最初のグループ (つまり: ) を検索し、[a-zA-Z0-9_]最初に一致したグループを返すかNone、失敗した場合に返します。

def test(str):
    m = re.search(r'(\w+)', str)
    if m:
        return m.group(1)
    return None

同じ関数を次のように書き換えることができます。

def test2(str):
    m = re.search(r'(\w+)', str)
    return m and m.group(1)

これは同じように機能し、文書化された動作です。このページには次のように明確に記載されています。

x and yは最初に評価されxます。が false の場合x、その値が返されます。それ以外の場合yは評価され、結果の値が返されます。

ただし、ブール演算子であるため(マニュアルにもそう記載されています)、andブール値を返すことを期待していました。その結果、これが(どのように)機能するかを知ったとき 、私は驚きました。

これの他のユースケースは何ですか、および/またはこのかなり非直感的な実装の理論的根拠は何ですか?

4

5 に答える 5

6

これの他の使用例は何ですか、

簡潔さ(したがって、慣れるとすぐに明確になります。結局のところ、読みやすさをまったく犠牲にしないためです!-)何かをチェックし、それが真実であればその何かを使用し、それが何かである場合は別の値を使用する必要があるときはいつでもは false です (これは for and-- 逆に for or--だけでなく、すべてのオブジェクトについて話しているため、実際のキーワードまたは類似のandを非常に意図的に避けています)。TrueFalsebool

コンピューター画面の垂直方向のスペースは限られています。選択肢があれば、次のような行を回すよりも、有用な読みやすさの補助 (docstring、コメント、ブロックを区切るために戦略的に配置された空行など) に費やすのが最善です。

inverses = [x and 1.0/x for x in values]

次のように 6 つに分けられます。

inverses = []
for x in values:
    if x:
        inverses.append(1.0/x)
    else:
        inverses.append(x)

またはそのより窮屈なバージョン。

および/または、このかなり非直感的な実装の理論的根拠は何ですか?

「直感的でない」どころか、(標準的な Pascal のような) 一部の言語では評価の順序と and の短絡的な性質が指定されていないという事実に、初心者は定期的につまずきまし。Turbo Pascal と言語標準の違いの 1 つは、当時 Turbo を常に最も人気のある Pascal 方言にしたものであり、Turbo が実装したものとまったく同じであり、後に Python が行ったように (そして C 言語が以前に行った...) .andorandor

于 2010-09-30T03:39:34.467 に答える
4

これの他の使用例は何ですか、

いいえ。

このかなり非直感的な実装の理論的根拠は何ですか?

「直感的でない」?本当に?私は同意しません。

考えましょう。

が false の場合、「a and b」は改ざんされます。aしたがって、答えを知るには最初の偽の値で十分です。なぜわざわざa別のブール値に変換するのですか? それはもう嘘です。はどれくらい偽Falseですか?同様に間違っていますよね?

したがってa、 の値 -- と同等の場合False-- は十分に false であるため、それが式全体の値です。それ以上の変換または処理はありません。終わり。

aの値が と等しい場合Trueb必要なのは の値だけです。それ以上の変換または処理はありません。bなぜ別のブール値に変換するのですか? その価値は、私たちが知る必要があるすべてです。のようなものであればTrue、それで十分です。はどれくらい真実Trueですか?

偽の追加オブジェクトを作成する理由

またはの同じ分析。

ブール値に変換する理由 それはすでに十分に正しいか、十分に間違っています。それはどれだけ真を得ることができますか?


これを試して。

>>> False and 0
False
>>> True and 0
0
>>> (True and 0) == False
True

(True and 0)ですが、実際には に0等しくなりFalseます。それはすべての実用的な目的には十分です。

問題がある場合bool(a and b)は、明示的な変換を強制します。

于 2010-09-30T00:10:23.143 に答える
1

基本的a and bに、式全体と同じ真偽値を持つオペランドを返します。

少しややこしく聞こえるかもしれませんが、頭の中で考えてみてください: もしaisならFalsebもう問題ではありません (False and anything常に になるからですFalse) a

しかし、それはいつaが問題なので、見ずにすぐに戻ってきます。Truebb

これは、多くの言語が行う非常に一般的で基本的な最適化です。

于 2010-09-29T23:56:20.917 に答える
0

この表記法は「機能する」一方で、ロジックを隠し、他の言語の大部分がどのように機能するかについて「荷物」を持っている経験豊富なプログラマーを混乱させる貧弱なコーディング スタイルを表していると思います。

ほとんどの言語では、アクティブな関数の戻り値は関数の型によって決まります。明示的にオーバーロードされていない限り。例 'strlen' タイプの関数は、文字列ではなく整数を返すことが期待されています。

コアの関節炎関数や論理関数 (+-/*|&!) などのインライン関数は、その背後に形式的な数学理論の歴史があるため、さらに制限されています。(これらの関数の操作の順序に関するすべての引数について考えてください)

基本的な関数が最も一般的なデータ型 (論理型または数値型) 以外のものを返すようにすることは、意図的な難読化として分類する必要があります。

ほぼすべての一般的な言語で、「&」、「&&」、または「AND」は論理関数またはブール関数です。舞台裏では、最適化コンパイラは、ロジック フローで上記のようなショートカット ロジックを使用する場合がありますが、データ構造の変更では使用しません (この方法で値を変更した最適化コンパイラは壊れていると見なされます)。ただし、値が変数で使用されることが予想される場合さらに処理するには、ロジックまたはブール型にする必要があります。これは、ほとんどの状況でこれらの演算子の「正式な」ものであるためです。

于 2014-11-26T17:30:35.670 に答える
0

これは驚くべきことではなく、実際、最初に試したときはうまくいくと思っていました。

すべての値が であるわけではありませんが、実際にはすべての値がブールbools値であることに注意してください。これらは真の値を表します。(Python では、aは事実上、true または falseのみを表す値です。) 数値はブール値ではありませんが、(Python では) 明示的にブール値 False を持ちます。bool0

つまり、ブール演算子andは常に を返すとは限りませんboolが、常にブール値を返します。他の情報が論理的に関連付けられている場合でも、true または false を表すもの (例: 文字列)。

おそらくこれは遡及的な正当化です。よくわかりませんが、いずれにせよ、Python のブール演算子がそのように振る舞うのは当然のことのようです。


いつ使用するのですか?

あなたの例では、 test2 がより明確に感じられます。どちらも同じように機能することがわかります。test2 の構造によって、理解が難しくなることはありません。他のすべてが同じであれば、test2 のコードが簡潔であるほど、わずかですが、より速く理解できます。とは言っても、それは些細な違いであり、何かを書き直すためにジャンプするほどどちらも好きではありません。

他の方法でも同様に役立ちます。

a = {
    "b": a and a.val,
    "c": b and b.val2,
    "d": c and c.val3,
}

これは別の方法で書き直すこともできますが、これは明確で、率直で、簡潔です。

船外に出ないでください。「a()? b():c()」の代わりに「a() and b() or c()」を使用するのは危険で混乱を招きます。間違い。3 項ステートメントを作成している場合は、3 項構文を使用してくださいb() if a() else c()

于 2010-09-29T23:47:49.570 に答える