所以我曾经在一种python类中提供以下代码。它真的是一个离散的数学课,但他使用python来演示一切。该代码应该用于演示多路复用器并用它构建xor门。
def mux41(i0,i1,i2,i3):
return lambda s1,s0:{(0,0):i0,(0,1):i1,(1,0):i2,(1,1):i3}[(s1,s0)]
def xor2(a,b):
return mux41(0,1,1,0)(a,b)
在xor2
函数中,我不理解return mux41(0,1,1,0)(a,b)
背后的语法,1和0是多路复用函数的输入,但是(a,b)做什么?
答案 0 :(得分:12)
(a, b)
实际上是您在lambda
函数中返回的mux41
函数的输入。
您的mux41
函数返回lambda
函数,该函数看起来像是根据mux41
函数的输入在字典中返回值。您需要第二个输入来说明要返回的值。
它直接相当于:
def xor2(a,b):
f = mux41(0,1,1,0)
return f(a,b)
答案 1 :(得分:5)
这是投入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)]
这定义了一个函数对象,它根据两个输入返回一个值。这两个输入为s1
和s0
。函数对象构建一个字典,该字典预先填充了传递给mux41()
的int的四个值,并使用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)
编辑:还有一件事发生在我身上。在Python中,规则是“逗号制作元组”。元组周围的括号有时是可选的。我刚检查过,它可以正常工作,在字典查找中省略括号。所以你可以这样做:
def xor2(a,b):
return _d_xor2[a, b]
它工作正常。这可能有点太棘手了?如果我在其他人的代码中看到这个,那会让我感到惊讶。