5

所以我一直在某种 python 类中给出以下代码。它确实是一门离散数学课,但他使用 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)]

def xor2(a,b):
    return mux41(0,1,1,0)(a,b)

xor2函数中,我不明白 1 和 0 背后的语法return mux41(0,1,1,0)(a,b)是 mux 函数的输入,但是 (a,b) 在做什么?

4

2 回答 2

12

(a, b)实际上是lambda您在函数中返回的mux41函数的输入。

您的mux41函数返回一个lambda函数,该函数看起来像是根据mux41函数的输入返回字典中的值。您需要第二个输入来说明要返回的值。

直接等价于:

def xor2(a,b):
    f = mux41(0,1,1,0)
    return f(a,b)
于 2013-02-01T23:46:10.453 回答
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)]

这定义了一个基于两个输入返回值的函数对象。两个输入是s1s0。该函数对象构建了一个字典,该字典预先填充了传递给 int 的四个值mux41(),并且它使用s0ands1来选择这四个值之一。

字典使用键来查找值。在这种情况下,键是 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() 并获取一个函数对象;然后它立即调用返回的函数对象,传入ab作为参数。最后它返回答案。

创建的函数对象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]

它工作正常。这可能有点太棘手了?如果我在别人的代码中看到这一点,我会感到惊讶。

于 2013-02-01T23:55:27.657 回答