百分号是什么意思?
它是 Python 中的一个运算符,根据上下文可以表示多种含义。其他答案中已经提到(或暗示)了以下很多内容,但我认为提供更广泛的摘要可能会有所帮助。
%
对于数字:模运算/余数/余数
百分号是Python 中的运算符。它被描述为:
x % y remainder of x / y
因此,如果您将 x 除以 y ,它会为您提供剩余/剩余部分 。通常(至少在 Python 中)给出一个数字x
和一个除数y
:
x == y * (x // y) + (x % y)
例如,如果您将 5 除以 2:
>>> 5 // 2
2
>>> 5 % 2
1
>>> 2 * (5 // 2) + (5 % 2)
5
通常,您使用模运算来测试一个数字是否被另一个数字整除,这是因为一个数字的倍数模该数字返回 0:
>>> 15 % 5 # 15 is 3 * 5
0
>>> 81 % 9 # 81 is 9 * 9
0
这就是它在您的示例中的使用方式,如果它是另一个数字的倍数(除了它自己和一个),它就不能是素数,这就是它的作用:
if n % x == 0:
break
如果您觉得这n % x == 0
不是很具有描述性,您可以将其放在另一个具有更具描述性名称的函数中:
def is_multiple(number, divisor):
return number % divisor == 0
...
if is_multiple(n, x):
break
取而代之的是is_multiple
它也可以被命名evenly_divides
或类似的东西。这就是这里测试的内容。
与此类似,它通常用于确定数字是“奇数”还是“偶数”:
def is_odd(number):
return number % 2 == 1
def is_even(number):
return number % 2 == 0
在某些情况下,当需要环绕(循环)行为时,它还用于数组/列表索引,然后您只需将“索引”乘以“数组长度”即可实现:
>>> l = [0, 1, 2]
>>> length = len(l)
>>> for index in range(10):
... print(l[index % length])
0
1
2
0
1
2
0
1
2
0
operator.mod
请注意,标准库(和别名)中也有此运算符的函数operator.__mod__
:
>>> import operator
>>> operator.mod(5, 2) # equivalent to 5 % 2
1
但也有%=
将结果分配回变量的扩充赋值:
>>> a = 5
>>> a %= 2 # identical to: a = a % 2
>>> a
1
对于字符串,含义完全不同,有一种方法(在我看来是最有限和最丑陋的)进行字符串格式化:
>>> "%s is %s." % ("this", "good")
'this is good'
这里%
字符串中的 代表一个占位符,后跟一个格式规范。在这种情况下,我使用%s
了这意味着它需要一个字符串。然后字符串后面跟着a %
,表示左侧的字符串将被右侧格式化。在这种情况下,第一个%s
被第一个参数替换,this
第二个%s
被第二个参数替换(good
)。
请注意,格式化字符串有更好的(可能是基于意见的)方法:
>>> "{} is {}.".format("this", "good")
'this is good.'
%
在 Jupyter/IPython 中:魔术命令
引用文档:
致 Jupyter 用户:魔术是 IPython 内核特有的并由其提供。内核是否可以使用魔法是内核开发人员基于每个内核做出的决定。为了正常工作,Magics 必须使用在底层语言中无效的语法元素。例如,IPython 内核使用%
魔法的语法元素,因为%
它不是 Python 中有效的一元运算符。而语法元素在其他语言中具有意义。
这经常用于 Jupyter notebooks 和类似的:
In [1]: a = 10
b = 20
%timeit a + b # one % -> line-magic
54.6 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [2]: %%timeit # two %% -> cell magic
a ** b
362 ns ± 8.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
数组运算符(在%
NumPy / Pandas 生态系统中)
%
当应用于这些数组时,该运算符仍然是模运算符,但它返回一个数组,其中包含数组中每个元素的余数:
>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a % 2
array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1])
%
为您自己的类自定义运算符
当然,您可以自定义将%
运算符应用于自己的类时的工作方式。通常你应该只用它来实现模运算!但这是一个指导方针,而不是硬性规定。
只是为了提供一个简单的例子来说明它是如何工作的:
class MyNumber(object):
def __init__(self, value):
self.value = value
def __mod__(self, other):
print("__mod__ called on '{!r}'".format(self))
return self.value % other
def __repr__(self):
return "{self.__class__.__name__}({self.value!r})".format(self=self)
这个例子并不是很有用,它只是打印然后将操作符委托给存储的值,但它显示了在应用于实例__mod__
时调用:%
>>> a = MyNumber(10)
>>> a % 2
__mod__ called on 'MyNumber(10)'
0
请注意,它也适用于%=
无需明确实现__imod__
:
>>> a = MyNumber(10)
>>> a %= 2
__mod__ called on 'MyNumber(10)'
>>> a
0
但是,您也可以__imod__
显式实现以覆盖增强的分配:
class MyNumber(object):
def __init__(self, value):
self.value = value
def __mod__(self, other):
print("__mod__ called on '{!r}'".format(self))
return self.value % other
def __imod__(self, other):
print("__imod__ called on '{!r}'".format(self))
self.value %= other
return self
def __repr__(self):
return "{self.__class__.__name__}({self.value!r})".format(self=self)
现在%=
被显式覆盖以就地工作:
>>> a = MyNumber(10)
>>> a %= 2
__imod__ called on 'MyNumber(10)'
>>> a
MyNumber(0)