以下行完成了啥? [复制]

Posted

技术标签:

【中文标题】以下行完成了啥? [复制]【英文标题】:What does the following line accomplish? [duplicate]以下行完成了什么? [复制] 【发布时间】:2020-09-09 01:01:49 【问题描述】:

所以我试图解决一种算法,并在尝试寻找其他解决方案的同时,我发现了一个非常短且非常快的解决方案,只是一个问题......我似乎无法理解这条线在做什么:

完整解决方案:

def proper_fractions(n):
    phi = n > 1 and n
    print(phi)
    for p in range(2, int(n ** .5) + 1):
        if not n % p:
            phi -= phi // p
            while not n % p:
                n //= p
    if n > 1: phi -= phi // n
    return phi

我不明白的行:

phi = n > 1 and n

请见谅如果很容易理解,我只是从来没有遇到过这样的事情,我只在if语句中使用了and,这是我将行改为(我认为像另一个一样工作,但不确定另一个是如何完全按照我更改的以下行所做的):

phi = n if n > 1 else False

请有人能解释一下我不明白的线路是如何工作的吗?

【问题讨论】:

False 也等于 0 @KlausD。是的,我知道 0 是假的,但我仍然不明白“那个”行的作用,如果n > 1,它甚至如何分配 n? 这不是我写的。 【参考方案1】:

首先,它首先检查第一个评估是真还是假(空值被认为是假)。然后如果为真,将返回第二个值。在这种情况下,n.

更多细节:

> if n = 3
> 1. phi = n > 1 and n
> 2. phi = 3 > 1 and 3
> 3. phi = True and 3
> 4. phi = 3

【讨论】:

True and True怎么变成3了? 关闭!但是根本没有第二个操作数的布尔转换,因为不需要。如果第一个操作数为真,and 只返回第二个操作数。无论第二个操作数是真还是假,这都会产生正确的结果。 它首先检查评估是否为真,如果是,则分配检查的最新值。在这种情况下,它是 n。【参考方案2】:

a and b真值表如下所示:

True  and True  == True
True  and False == False
False and True  == False
False and False == False

我们可以观察到三件事:

aTrue 时,结果始终与b 相同。 当aFalse时,结果始终为False,即始终与a相同。 当aFalse 时,b 完全不相关,所以我们甚至不需要评估它。

请注意,在 Python 中,True and False are not the only objects that have a boolean value。事实上,Python 中的每一个对象 都有一个布尔值。例如。 0 有一个 falsey 值,"Hello" 有一个 truthy 值,以此类推。

因此,通过我们发现的关于真值表的优化,以及我们需要处理除TrueFalse 之外的值的附加条件,我们可以构造以下修改后的真值表:

a and b == a # if `a` is *falsey*
a and b == b # if `a` is *truthy*

这与the documentation of and匹配:

表达式x and y首先计算x;如果 x 为 false,则返回其值;否则,评估 y 并返回结果值。

类似的推理也适用于or

a or b == b # if `a` is *falsey*
a or b == a # if `a` is *truthy*

所以,有问题的行的结果:

phi = n > 1 and n

如果n <= 1n 如果n > 1 则分配phi False

使用phi 执行的进一步计算又会起作用,因为False 在数字上下文中等效于0,即

False + 1 ==  1
False - 1 == -1

这使得算法的其余部分工作,其中包含如下语句:

phi -= phi // p

使用phi 的值执行算术运算。

详见the documentation on the numeric types,其中包含以下语句[bold强调我的]:

共有三种不同的数值类型:整数浮点数复数。此外,布尔值是整数的子类型

【讨论】:

【参考方案3】:

来自documentation 的第 6.11 节:

表达式 x 和 y 首先计算 x;如果 x 为假,则返回其值;否则,计算 y 并返回结果值。

请注意,and 或 or 都不会限制它们返回的值和类型为 False 和 True,而是返回最后评估的参数。这有时很有用,例如,如果 s 是一个字符串,如果它是空的,则应该将其替换为默认值,则表达式 s 或 'foo' 会产生所需的值。因为 not 必须创建一个新值,所以无论其参数的类型如何,它都会返回一个布尔值(例如,not 'foo' 产生 False 而不是 ''。)

所以它首先检查n是否>1,如果为真,则返回s n,否则返回False。

【讨论】:

【参考方案4】:

从Python docs 中可以看出,Python 逻辑运算符不一定是“纯布尔值”。特别是,andor 实际上并不能保证返回 TrueFalse。相反,它们返回其操作数之一。下面是 Python 定义x and y 值的方式:

如果 x 为假,则为 x,否则为 y

在此上下文中的“False”并不意味着 x 必须是值 False。相反,它必须是任何具有虚假值的东西,例如任何类型的零或空序列或集合。

在这种情况下,当n > 1 计算False 时,运算符会短路并返回n > 1,也称为False。但是,如果 n > 1 评估 True,则运算符只需返回 n 而无需以任何方式修改它,如文档所述。

【讨论】:

以上是关于以下行完成了啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

hash_table 初始化,发生了啥? [复制]

在 python 中定义字符串时,开头的 'u 做了啥? [复制]

我在我的 Angular HTML 模板中做错了啥? [复制]

编译器在这里做了啥:int a = b * (c * d * + e)? [复制]

UIViewController 类在 viewDidLoad 中做了啥? [复制]

vulkan API 复制了啥?