Python中的%运算结果是什么?
在计算中,%
这个符号是用来表示“取余”的,也就是说它会告诉你两个数字相除后,剩下的部分是多少。
比如说,4 % 2
的意思是用4去除以2,看看剩下多少。因为4除以2正好是2,没有剩下的,所以结果是0。
20 个回答
b*q + r = a and 0 <= r < b
像 x % y
这样的表达式会计算 x ÷ y
的余数——严格来说,它是“模运算”,而不是“余数”,所以如果你在和其他语言比较时,结果可能会不同,因为在那些语言中 %
是余数运算符。这里有一些细微的区别(如果你对实际影响感兴趣,可以看看下面的“为什么Python的整数除法向下取整”)。
优先级和运算符 /
(除法)和 *
(乘法)是一样的。
>>> 9 / 2
4
>>> 9 % 2
1
- 9 除以 2 等于 4。
- 4 乘以 2 是 8。
- 9 减去 8 是 1——就是余数。
Python的小知识:根据你使用的Python版本,%
也是(已弃用的)字符串插值运算符,所以如果你来自于像PHP或JS这样的语言,那里表达式 '12' % 2 + 3
是合法的:在Python中会导致 TypeError: not all arguments converted during string formatting
,这可能会让你感到困惑。
[Python 3的更新]
用户 n00p 评论说:
在Python中,9/2 是 4.5。如果你想让Python告诉你除法后剩下多少个完整的对象(4),你得用整数除法:9//2。
准确地说,整数除法在Python 2中是默认的(请注意,这个回答比我儿子上学的时间还要早,那时2.x是主流):
$ python2.7
Python 2.7.10 (default, Oct 6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1
在现代Python中,9 / 2
的结果确实是 4.5
:
$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1
[更新]
用户 dahiya_boy 在评论中问:
问. 能解释一下为什么
-11 % 5 = 4
吗? - dahiya_boy
这听起来有点奇怪,对吧?如果你在JavaScript中试试:
> -11 % 5
-1
这是因为在JavaScript中,%
是“余数”运算符,而在Python中它是“模运算”(时钟数学)运算符。
你可以直接从 GvR那里获得解释:
编辑 - dahiya_boy
在Java和iOS中,-11 % 5 = -1
,而在Python和Ruby中,-11 % 5 = 4
。
原因的一部分由 Paulo Scardine 解释,剩下的解释在下面。
在Java和iOS中,%
给出的余数意味着如果你计算 11 % 5 得到 商 = 2 和 余数 = 1
,而 -11 % 5 得到 商 = -2 和 余数 = -1
。
Swift iOS中的示例代码。
但在Python中,它给出的结果是时钟模运算。它的计算公式如下:
mod(a,n) = a - {n * Floor(a/n)}
这意味着,
mod(11,5) = 11 - {5 * Floor(11/5)} => 11 - {5 * 2}
所以,mod(11,5) = 1
而
mod(-11,5) = -11 - 5 * Floor(-11/5) => -11 - {5 * (-3)}
所以,mod(-11,5) = 4
Python 3.0中的示例代码。
为什么Python的整数除法向下取整
今天有人问我(又一次)为什么Python中的整数除法返回结果的下限,而不是像C语言那样向零截断。
对于正数,这没有什么好惊讶的:
>>> 5//2
2
但是如果其中一个操作数是负数,结果就会向下取整,也就是远离零(朝向负无穷):
>>> -5//2
-3
>>> 5//-2
-3
这让一些人感到困扰,但这是有很好的数学原因的。整数除法操作(//)和它的兄弟模运算(%)是相辅相成的,并且满足一个很好的数学关系(所有变量都是整数):
a/b = q with remainder r
假设 a 和 b 都大于等于 0。
如果你想让这个关系扩展到负数 a(保持 b 为正),你有两个选择:如果你向零截断 q,余数 r 会变成负数,这样不等式就变成了 0 <= abs(r) <;否则,你可以向负无穷取整 q,这样不等式保持为 0 <= r < b。[更新:修正了这一段]
在数学数论中,数学家总是更喜欢后者(见例如 维基百科)。对于Python,我做了同样的选择,因为模运算有一些有趣的应用,其中 a 的符号并不重要。考虑获取一个POSIX时间戳(自1970年开始的秒数)并将其转换为一天中的时间。由于一天有24*3600 = 86400秒,这个计算就是 t % 86400。但是如果我们用负数表示1970年之前的时间,“向零截断”的规则会给出一个没有意义的结果!使用向下取整的规则一切都能正常工作。
我想到的其他应用是计算计算机图形中的像素位置。我相信还有更多。
顺便说一下,对于负数 b,一切都会翻转,不等式变为:
0 >= r > b.
那么为什么C语言不这样做呢?可能是因为在C语言设计时,硬件没有这样做。而硬件之所以没有这样做,是因为在最早的硬件中,负数是以“符号 + 数值”的方式表示,而不是现在使用的二进制补码表示(至少对于整数来说)。我第一台电脑是Control Data大型机,它使用的是一补数表示法。
Tim Peters,知道Python中所有浮点数的秘密,曾对我想将这些规则扩展到浮点数模运算表示担忧。他可能是对的;向负无穷截断的规则可能会导致当 x 是一个非常小的负数时,x%1.0 的精度损失。但这不足以让我打破整数模运算,而 // 与此紧密相关。
附言:请注意,我使用的是 // 而不是 /——这是Python 3的语法,在Python 2中也允许使用,以强调你知道你正在调用整数除法。在Python 2中,/运算符是模糊的,因为对于两个整数操作数,它返回的结果与一个整数和一个浮点数或两个浮点数的结果不同。但这是一个完全不同的故事;请参见PEP 238。
由Guido van Rossum于上午9:49发布
有点跑题了,%
这个符号也可以用在字符串格式化操作中,比如 %=
用来把值放进字符串里:
>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x
'abc_value_'
再次跑题,不过这似乎是一个文档里没怎么提到的功能,我花了一些时间才找到它,而且我原以为它和Python的取模计算有关,所以这个StackOverflow页面在搜索中排名很高。
%(取模)运算符的作用是计算第一个数字除以第二个数字后的余数。首先,这两个数字会被转换成一种共同的类型。如果第二个数字是零,就会出现一个叫做ZeroDivisionError的错误。这个运算符可以处理浮点数,比如说,3.14%0.7的结果是0.34(因为3.14等于4乘以0.7再加上0.34)。取模运算符的结果总是和第二个数字有相同的符号(或者是零);而且结果的绝对值一定小于第二个数字的绝对值。
摘自 http://docs.python.org/reference/expressions.html
例子 1:
6%2
的结果是 0
,因为6除以2没有余数(可以整除3次)。
例子 2: 7%2
的结果是 1
,因为7除以2有一个余数 1
(可以整除3次)。
总结一下,取模运算返回的是除法运算的余数,如果没有余数则返回 0
。所以 6%2
的意思就是找出6除以2的余数。