我想知道是否有人可以给我任何关于Python3中以下内容可能相同/不同的见解:
N // 1
Run Code Online (Sandbox Code Playgroud)
和
from math import floor
floor(N)
Run Code Online (Sandbox Code Playgroud)
我尝试了以下操作,似乎表明它们是等效的:
import math
import random
for _ in range(0, 99999):
f = random.random()
n = random.randint(-9999, 9999)
N = f * n
n_div = N // 1; n_mth = math.floor(N)
if n_div != n_mth:
print("N // 1: {} | math.floor(N): {}".format(n_div, n_mth))
else: # yes, I realize this will always run
print("Seem the same to me")
Run Code Online (Sandbox Code Playgroud)
感谢您在下面的评论。将测试更新为以下内容,该内容清楚地显示在python3中float // N返回float,而math.floor(N)返回。据我了解,此行为在python2中不同,其中where 和return s。int math.ceilmath.floorfloat
同样要注意不同寻常的/傻它是使用math.ceil或math.floor上int,而不是一个float:上功能操作要么int简单地返回int。
import math
import random
for _ in range(0, 99):
N = random.uniform(-9999, 9999)
n_div = N // 1; n_mth = math.floor(N)
if n_div != n_mth:
print("N: {} ... N // 1: {} | math.floor(N): {}".format(N, n_div, n_mth))
elif type(n_div) != type(n_mth):
print("N: {} ... N // 1: {} ({}) | math.floor(N): {} ({})".format(N, n_div, type(n_div), n_mth, type(n_mth)))
else:
print("Seem the same to me")
Run Code Online (Sandbox Code Playgroud)
使用浮点数时,您会发现不同之处:
>>> 1000.5//1
1000.0
>>> floor(1000.5)
1000
Run Code Online (Sandbox Code Playgroud)
floor返回一个整数。在大多数情况下1000与1000.0等效,但并非总是如此。
math.floor(N)返回一个整数,并N // 1返回一个浮点数。
>>> type(math.floor(-4.4))
<class 'int'>
>>> type((-4.4) // 1)
<class 'float'>
Run Code Online (Sandbox Code Playgroud)因为这floor(nan)会在nan // 1返回 NaN时引发 ValueError (类似于 ±inf。)
>>> math.floor(math.nan)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot convert float NaN to integer
>>> math.nan // 1
nan
Run Code Online (Sandbox Code Playgroud)我认为当 N 是浮点数时没有其他区别,因为它x//y被定义为 ⌊x/y⌋。
math.floor首先尝试使用__floor__魔法方法,如果它不存在,它会使用__float__然后将其地板,因此当对象支持__floor__或可以强制转换为float.
x//1使用__floordiv__魔术方法,如果未定义或返回NotImelemeted它,则尝试__rfloordiv__使用1几乎肯定是的整数NotImplemented,因此这需要__floordiv__在相关对象上实现。
from math import floor
class MyInt(int):
def __floor__(self):
print("using __floor__")
return int.__floor__(self)
def __floordiv__(self,other):
print("using __floordiv__")
return int.__floordiv__(self,other)
>>> x = MyInt(5)
>>> floor(x)
using __floor__
5
>>> x//1
using __floordiv__
5
Run Code Online (Sandbox Code Playgroud)
通常这两个值总是相等的,但可能以不同的方式实现这两个值,通常唯一显着的区别是返回值的类型,尽管根据您使用的对象类型可能会有更多实质性的变化:
>>> x = numpy.array([1.5, 2.3, 5])
>>> x//1
array([ 1., 2., 5.])
>>> floor(x)
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
floor(x)
TypeError: only length-1 arrays can be converted to Python scalars
Run Code Online (Sandbox Code Playgroud)