【问题标题】:Getting the return value of functions passed in as variables获取作为变量传入的函数的返回值
【发布时间】:2015-10-18 00:27:44
【问题描述】:

我目前正在尝试编写一个函数,该函数将两个真值函数作为其参数,并根据它们在逻辑上是否等效返回一个布尔值。例如,假设主要功能是

def logical_equiv(function1, function2):
    #function1 and function2 are truth functions

我已经通过做检查了两个传入的函数是否相同

def logical_equiv(function1, function2):
    if function1 == function2:
         return True

但是如何检查function1和function2的实际返回值呢?更清楚地说,假设 function1 接受两个参数 P 和 Q,然后返回(非 P)或(非 Q),而 function2 也接受两个参数 P 和 Q,然后返回 not(P 和 Q),我将如何在我的逻辑等效函数?我试过做

def logical_equiv(function1, function2):
     if function1 == (not P) or (not Q):
          #do something

但这会返回错误NameError: name 'P' is not defined 从logical_equiv打印出函数返回一个内存地址。

【问题讨论】:

  • 向我们展示“真实”代码和您遇到的错误。你不能说if function1 == function2:,因为你正在比较对象引用,所以这通常是错误的。您需要查看函数的参数数量,并且它们必须始终相同。然后你需要构造一个真值表(即输入和预期输出的布尔值数组),然后用一组布尔值调用每个函数并比较它们都返回相同的布尔值。
  • 我同意@dopstar...很难理解您为什么要查看function1function2 的内部代码,因此编辑您的帖子以包含您的具体问题会有所帮助.我知道 SO 是关于泛化的,但在这种情况下,我们需要看看。

标签: python python-3.x logic


【解决方案1】:

如果您想使用相同的参数查看它们是否在逻辑上等价:

def logical_equiv(function1, function2, *args):
    return function1(*args) == function2(*args)

然后:

>>> func1 = lambda P, Q: (not P) or (not Q)
>>> func2 = lambda P, Q: not(P and Q)
>>> logical_equiv(func1, func2, True, False)
True

这可以扩展到任意数量的参数:

>>> func1 = lambda P, Q, R: (not P) or (not Q) or (not R)
>>> func2 = lambda P, Q, R: not(P and Q and R)
>>> logical_equiv(func1, func2, True, False, True)
True

如果您需要为n 参数测试[True, False] 的所有有效组合,那么您可以这样做:

from itertools import product
def logical_equiv(f1, f2):
    n = f1.__code__.co_argcount        # @dopstart
    if n != f2.__code__.co_argcount:
        return False
    return all(f1(*args) == f2(*args) for args in product([True, False], repeat=n))

>>> func1 = lambda P, Q, R: (not P) or (not Q) or (not R)
>>> func2 = lambda P, Q, R: not(P and Q and R)
>>> logical_equiv(func1, func2)
True

【讨论】:

  • 逻辑等价的整个想法让我感到紧张。也许这就是OP想要的但是。如果function1是直线函数y = x,function2y = x^3是三次函数,你调用logical_equiv(func1, func2, 0)logical_equiv(func1, func2, 1)甚至logical_equiv(func1, func2, -1),如果他使用这些交点,人们会认为这两个函数在逻辑上是等价的但他们不是。
  • 同意,也许 OP 打算测试所有有效输入,这可以通过 n 参数 itertools.product([True, False], n) 的逻辑函数来实现,但对于连续函数则不行。
  • 假设 function1 返回与 ~P ∨ ~Q 等价的 python,当然这只是 return (not P) or (not Q),而 function2 返回 ~(P 和 Q),即 return not(P and Q)。 Python 已经知道这两个是相等的,但是在我的检查函数中,我不能只做 if function1 == function2。我无法弄清楚语法。
  • Python 如何知道它们是等价的? function1 == function2 只是检查 function1 的身份是否与 function2 的身份相同,只有当它们是相同的函数时才成立,即logical_equiv(func1, func1) -> True。您需要调用这些函数,例如function1() 并传入参数,如上面的代码所示。如果这不是您要查找的内容,请更新问题并提供更具体的详细信息。
  • 现在我不再担心你的逻辑等价函数了。好东西。你通过itertools.product 击败了我构建真值表,我不会发布我的答案。但是,您可以使用logical_equiv 来检测函数占用的参数数量(即f1.__code__.co_argcount,如果它们不相同,则返回False,因为它们不等价。然后该argcount 用于提供@ 987654343@ itertools.product 的参数,这样你就说logical_equiv(func1, func2)
【解决方案2】:

我想你会想这样做:

def logical_equiv(function1, function2):
     if function1() in [(not P), (not Q)]:
          #do something

当然,你需要定义PQ。请记住,function1 只是对函数的引用,而 function1() 调用函数并返回其值。

另外,要检查function1function2 的输出是否相等,只需执行以下操作:

if function1() == function2():
    ...

【讨论】:

  • 如果函数接受 N 个参数怎么办?
  • 但是function1和function2也带参数?
  • 如果他们采用多个参数,只需将函数调用更改为:function1(a, b)。你的意思是如果他们return 也有多个值吗?
  • 我的意思是像你提到的function1(a, b, c, d, ...) 的参数。但是,从数学上讲,我认为仅仅因为它们在某些特定的输入参数集“相交”而得出结论是等价的还不够。以这种方式,代码必须构建一个真值表并调用两个函数2^N。由于只有ab 2 个参数,因此必须针对所有2^2 = 4 场景比较函数。
  • 啊,不,你说得对。我将其误读为仅检查单个参数集。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多