挑战你,Python 益智题:如何让这个函数返回 True

Python

嗨,大家好!我正在浏览 /r/python 并遇到了 这篇文章:

有这样一个函数:

def check(x):
    if x+1 is 1+x:
        return False
    if x+2 is not 2+x:
        return False
    return True

提供一个输入,使得 1 加上它,还是和它是同个对象的实例,但是 2 加上它不再是同个对象的实例。

解决方案1:自定义类

我个人认为解决此挑战的方式是:

def check(x):
    if x+1 is 1+x:
        return False
    if x+2 is not 2+x:
        return False
    return True

class Test(int):
    def __add__(self, v):
        if v == 1:
            return 0
        else:
            return v

print(check(Test()))
# output: True

让我解释一下它是如何工作的。在 Python 中,当我们使用 + 运算符时,Python 会根据对象在运算符的哪一侧来调用不同的特殊方法。如果对象在运算符的左侧,则将调用 __ add __ ;如果在右侧,则将调用 __ radd __

如果调用了 Test() + 1 则返回 0,如果调用 1 + Test() 则返回 1。诀窍在于,我们只重载其中一种特殊方法,而另一种不变。这将帮我们通过第一个 if 条件。如果再看一遍,您会发现它也帮助我们通过了第二次的 if 检查,因为如果输入不是 1 的话,直接返回输入,所以 Test() + 2 永远等价于 2 + Test()

但是,在看了评论之后,我发现了另一个不需要自定义类的解决方案。

解决方案2:唯一的整数

用户 /u/SethGecko11 提出了出奇简单的答案:

def check(x):
    if x+1 is 1+x:
        return False
    if x+2 is not 2+x:
        return False
    return True

print(check(-7))
# output: True

只有 -7 可行。任何一个其他的数字都不会返回 True。如果您对为什么这样做感到困惑,那么您并不孤单。我必须阅读评论以找出原因。

很显然,在 Python 中,整数 -5 到 256 是预分配的。当您执行任何操作且结果在该范围内时,您将获得预分配的对象。这些都是单例,因此 is 运算符将返回 True。如果您尝试使用不属于此范围的整数,则会得到一个新实例。

预分配这些整数的内存要求不是很高,但是显然性能提升是巨大的。

因此,当您使用 -7 作为输入时,将得到一个新的 -6 实例,但当答案为 -5 时将获得相同的实例。正是由于 if 语句的构造方式,所以这对上限 (256) 无效。如果检查功能是这样实现的,则 255 可以作为答案:

def check(x):
    if x+1 is not 1+x:
        return False
    if x+2 is 2+x:
        return False
    return True

希望您在本文中学到了新东西。我认为您永远都不会在任何代码库中使用此功能,但是它是一个非常好的脑筋急转弯,甚至可以使经验丰富的 Python 开发人员措手不及。

编程愉快!

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://pythontips.com/2019/07/30/python...

译文地址:https://learnku.com/python/t/41356

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!