Python中的%运算结果是什么?

266 投票
20 回答
1294083 浏览
提问于 2025-04-16 08:28

在计算中,%这个符号是用来表示“取余”的,也就是说它会告诉你两个数字相除后,剩下的部分是多少。

比如说,4 % 2的意思是用4去除以2,看看剩下多少。因为4除以2正好是2,没有剩下的,所以结果是0。

20 个回答

62
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中的示例代码。

enter image description here

但在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中的示例代码。

enter image description here


为什么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发布

149

有点跑题了,% 这个符号也可以用在字符串格式化操作中,比如 %= 用来把值放进字符串里:

>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x 
'abc_value_'

再次跑题,不过这似乎是一个文档里没怎么提到的功能,我花了一些时间才找到它,而且我原以为它和Python的取模计算有关,所以这个StackOverflow页面在搜索中排名很高。

330

%(取模)运算符的作用是计算第一个数字除以第二个数字后的余数。首先,这两个数字会被转换成一种共同的类型。如果第二个数字是零,就会出现一个叫做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的余数。

撰写回答