これはPythonの初心者に投げかけるにはかなり高度なコードなので、気にしないでください。また、必要以上にトリッキーだと思います。
def mux41(i0,i1,i2,i3):
return lambda s1,s0:{(0,0):i0,(0,1):i1,(1,0):i2,(1,1):i3}[(s1,s0)]
これは、2つの入力に基づいて値を返す関数オブジェクトを定義します。s1
2つの入力はとですs0
。関数オブジェクトは、intに渡された4つの値が事前に入力されたディクショナリを構築し、それらの4つの値の1つをmux41()
使用s0
しs1
て選択します。
辞書はキーを使用して値を検索します。この場合、キーはPythonタプル:、、、、(0, 0)
およびです。式は、引数と。からタプルを構築しています。このタプルは、ディクショナリから値を検索するためのキーとして使用されます。(0, 1)
(1, 0)
(1,1)
(s1,s0)
s0
s1
def xor2(a,b):
return mux41(0,1,1,0)(a,b)
したがって、mux41()
先ほど説明したことを実行する関数オブジェクトを返します。 関数オブジェクトをxor2()
呼び出して取得します。mux41()
次に、返された関数オブジェクトをすぐに呼び出し、引数として渡しa
ますb
。最後に答えを返します。
によって作成された関数オブジェクトmux41()
はどこにも保存されません。したがって、を呼び出すたびにxor2()
、関数オブジェクトを作成し、それをガベージコレクションします。関数オブジェクトを実行すると、ディクショナリオブジェクトが作成されます。これも、使用するたびにガベージコレクションされます。これはおそらく私が今まで見た中で最も複雑なXOR関数です。
これを少し明確にするかもしれない書き直しがあります。lambda
名前のない関数オブジェクトを作成するために使用する代わりにdef
、名前の付いた関数を作成するために使用します。
def mux41(i0,i1,i2,i3):
def mux_fn(s1, s0):
d = {
(0,0):i0,
(0,1):i1,
(1,0):i2,
(1,1):i3
}
tup = (s1, s0)
return d[tup]
return mux_fn
def xor2(a,b):
mux_fn = mux41(0,1,1,0)
return mux_fn(a,b)
編集:PythonでテーブルルックアップXORを作成したい場合は、次のように記述します。
_d_xor2 = {
(0,0) : 0,
(0,1) : 1,
(1,0) : 1,
(1,1) : 0
}
def xor2(a,b):
tup = (a, b)
return _d_xor2[tup]
ルックアップ辞書を一度作成してから、から直接使用しxor2()
ます。で明示的な一時変数を作成する必要はxor2()
ありませんが、少し明確になる可能性があります。あなたはこれを行うことができます:
def xor2(a,b):
return _d_xor2[(a, b)]
どっちがいい?
もちろん、PythonにはXOR演算子が組み込まれているため、次のように記述できます。
def xor2(a,b):
return a ^ b
これを実際に書いているとしたら、おそらくエラー処理を追加したり、bool
値を操作するようにしたりします。
def xor2(a,b):
return bool(a) ^ bool(b)
編集:もう1つ私に起こったことがあります。Pythonでは、ルールは「コンマがタプルを作成する」です。タプルを囲む括弧はオプションの場合があります。チェックしたところ、辞書ルックアップで括弧を省略しても問題なく機能します。だからあなたはこれを行うことができます:
def xor2(a,b):
return _d_xor2[a, b]
そしてそれはうまくいきます。これはおそらく少しトリッキーすぎますか?これを他の誰かのコードで見た場合、それは私を驚かせるでしょう。