百分号在Python中意味着什么

Lon*_*ice 50 python operators modulo

在教程中有一个查找素数的示例:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
Run Code Online (Sandbox Code Playgroud)

我知道双重==是对平等的考验,但我不理解这一if n % x部分.就像我可以口头遍历每个部分并说出该声明对该示例的作用.但我不明白百分号是如何落入的.

什么是if n % x真正说什么?

Sin*_*ion 117

%根据其参数做两件事.在这种情况下,它充当模运算符,意味着当它的参数是数字时,它将第一个除以第二个并返回余数. 34 % 10 == 4因为34除以10是3,其余为4.

如果第一个参数是字符串,则使用第二个参数对其进行格式化.这有点涉及,所以我将参考文档,但作为一个例子:

>>> "foo %d bar" % 5
'foo 5 bar'
Run Code Online (Sandbox Code Playgroud)

但是,从Python 3.1开始补充字符串格式化行为,以支持字符串.format()机制:

这里描述的格式化操作表现出各种怪癖,导致许多常见错误(例如无法正确显示元组和字典).使用较新的str.format()界面有助于避免这些错误,并且还提供了一种通常更强大,灵活且可扩展的格式化文本的方法.

值得庆幸的是,几乎所有的新功能都可以从python 2.6开始提供.

  • 文档说:"%运算符由*更强大的字符串格式化方法*格式(*)补充*." 我不认为这意味着删除/弃用. (3认同)
  • 我相信字符串格式化操作符在 Python 3 中被删除了。 (2认同)
  • @David:它刚被弃用了. (2认同)
  • @Leftium http://docs.python.org/3/whatsnew/3.0.html#pep-3101-a-new-approach-to-string-formatting声明`%`将在python 3.1中被弃用并且'从'以后的语言'.但是,该页面已经很老了.我在python 3.2或3.3文档中找不到任何提及它.我希望开发者改变主意并决定保持`%`原样.`format()`很好而且功能强大,但`%`对基本用法来说更方便. (2认同)

ink*_*dmn 56

模数算子; 给左值的余数除以右值.喜欢:

3 % 1 将等于零(因为3将1均分为1)

3 % 2 将等于1(因为将3除以2导致余数为1).

  • 仅供参考,称为欧几里得分部 (2认同)
  • 冒着迂腐的风险,我想我应该澄清模数(%)与负数的余数不同。-2 / 3 的余数为 -2,但 -2 % 3 = 1 (2认同)

Ste*_*hen 21

虽然这有点偏离主题,因为人们会通过搜索"Python中的百分号"(就像我所做的那样)找到这个,我想要注意%符号也用于在iPython中为"魔术"函数添加前缀:https ://ipython.org/ipython-doc/3/interactive/tutorial.html#magic-functions


MSe*_*ert 12

百分号是什么意思?

它是Python中的一个运算符,根据上下文可能意味着几个东西.在其他答案中已经提到(或暗示)了很多内容,但我认为提供更广泛的摘要可能会有所帮助.

% 对于数字:模运算/余数/余数

百分号是Python中运算符.它被描述为:

x % y       remainder of x / y
Run Code Online (Sandbox Code Playgroud)

所以,它给你的剩余/剩下的是 保持如果"分楼",由Y X.通常(至少在Python中)给出一个数字x和一个除数y:

x == y * (x // y) + (x % y)
Run Code Online (Sandbox Code Playgroud)

例如,如果将5除以2:

>>> 5 // 2
2
>>> 5 % 2
1

>>> 2 * (5 // 2) + (5 % 2)
5
Run Code Online (Sandbox Code Playgroud)

通常,您使用模运算来测试数字是否均匀地除以另一个数字,这是因为以该数字为模的数字的倍数返回0:

>>> 15 % 5  # 15 is 3 * 5
0

>>> 81 % 9  # 81 is 9 * 9
0
Run Code Online (Sandbox Code Playgroud)

这就是它在你的例子中使用的方式,如果它是另一个数字的倍数(除了它自己和一个),它就不能成为素数,这就是它的作用:

if n % x == 0:
    break
Run Code Online (Sandbox Code Playgroud)

如果您觉得这n % x == 0不是非常具有描述性,可以将其放在具有更具描述性名称的另一个函数中:

def is_multiple(number, divisor):
    return number % divisor == 0

...

if is_multiple(n, x):
    break
Run Code Online (Sandbox Code Playgroud)

而不是is_multiple它也可以被命名evenly_divides或类似的东西.这是在这里测试的.

类似于它通常用于确定数字是"奇数"还是"偶数":

def is_odd(number):
    return number % 2 == 1

def is_even(number):
    return number % 2 == 0
Run Code Online (Sandbox Code Playgroud)

在某些情况下,当需要环绕(循环)行为时,它也用于数组/列表索引,然后您只需通过"数组长度"对"索引"进行模数化即可实现:

>>> 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
Run Code Online (Sandbox Code Playgroud)

请注意,标准库operator.mod(和别名operator.__mod__)中还有此运算符的函数:

>>> import operator
>>> operator.mod(5, 2)  # equivalent to 5 % 2
1
Run Code Online (Sandbox Code Playgroud)

但是还有增强赋值%=,它将结果赋给变量:

>>> a = 5
>>> a %= 2  # identical to: a = a % 2
>>> a
1
Run Code Online (Sandbox Code Playgroud)

%for strings:printf-style String Formatting

对于字符串来说,意思是完全不同的,那就是进行字符串格式化的一种方式(在我看来,最有限和最丑陋):

>>> "%s is %s." % ("this", "good") 
'this is good'
Run Code Online (Sandbox Code Playgroud)

这里的%字符串表示占位符,后跟格式规范.在这种情况下,我使用的%s意思是它需要一个字符串.然后字符串后跟一个%表示左侧的字符串将由右侧格式化的字符串.在这种情况下,第一%s是由第一个参数替换this和第二%s被第二参数替换(good).

请注意,格式化字符串有更好的(可能是基于意见的)方法:

>>> "{} is {}.".format("this", "good")
'this is good.'
Run Code Online (Sandbox Code Playgroud)

% 在Jupyter/IPython中:魔术命令

引用文档:

对于Jupyter用户:Magics是IPython内核特有的并由其提供.内核开发人员是否在内核基础上做出了决定.要正常工作,Magics必须使用在底层语言中无效的语法元素.例如,IPython内核使用%magics 的语法元素,因为%它不是Python中有效的一元运算符.而语法元素在其他语言中具有意义.

这经常用于Jupyter笔记本和类似的:

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)
Run Code Online (Sandbox Code Playgroud)

%阵列上的运算符(在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])
Run Code Online (Sandbox Code Playgroud)

%为您自己的类定制运算符

当然,您可以在%应用运算符时自定义自己的类的工作方式.通常,您应该只使用它来实现模运算!但这是一个指导方针,而不是一个硬性规则.

只是提供一个简单的例子来说明它是如何工作的:

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)
Run Code Online (Sandbox Code Playgroud)

这个例子不是很有用,它只是打印然后将操作符委托给存储的值,但它显示了__mod__%应用于实例时调用:

>>> a = MyNumber(10)
>>> a % 2
__mod__ called on 'MyNumber(10)'
0
Run Code Online (Sandbox Code Playgroud)

请注意,它也适用于%=没有明确需要实现__imod__:

>>> a = MyNumber(10)
>>> a %= 2
__mod__ called on 'MyNumber(10)'

>>> a
0
Run Code Online (Sandbox Code Playgroud)

但是,您也可以__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)
Run Code Online (Sandbox Code Playgroud)

现在%=被明确覆盖以便就地工作:

>>> a = MyNumber(10)
>>> a %= 2
__imod__ called on 'MyNumber(10)'

>>> a
MyNumber(0)
Run Code Online (Sandbox Code Playgroud)