Oli*_*ain 5 python arrays numpy
出于某种原因,evalRow(list(array([0, 1, 0, 0, 0])))并evalRow([0, 1, 0, 0, 0])给出不同的结果.但是如果我使用magicConvert(这里调试这个)而不是list从numpy数组转到列表它按预期工作.这是numpy中的一个错误吗?
def magicConvert(a):
ss = str(list(a))[1:-1]
return map(int, ss.split(","))
# You don't actually need to read these functions, just here to reproduce the error:
from itertools import *
def evalRow(r):
grouped = map(
lambda (v, l): (v, len(tuple(l))),
groupby(chain([2], r, [2])))
result = 0
for player in (1, -1):
for (pre, mid, post) in allTuples(grouped, 3):
if mid[0] == player:
result += player * streakScore(mid[1], (pre[0] == 0) + (post[0] == 0))
return result
def streakScore(size, blanks):
return 0 if blanks == 0 else (
100 ** (size - 1) * (1 if blanks == 1 else 10))
def allTuples(l, size):
return map(lambda i: l[i : i + size], xrange(len(l) - size + 1))
Run Code Online (Sandbox Code Playgroud)
Bak*_*riu 10
行为的差异是由于do list(some_array)返回一个列表numpy.int64,而通过字符串表示进行转换(或等效地使用该tolist()方法)返回python的列表int:
In [21]: import numpy as np
In [22]: ar = np.array([1,2,3])
In [23]: list(ar)
Out[23]: [1, 2, 3]
In [24]: type(list(ar)[0])
Out[24]: numpy.int64
In [25]: type(ar.tolist()[0])
Out[25]: builtins.int
Run Code Online (Sandbox Code Playgroud)
我相信罪魁祸首是100 ** (size - 1)你的代码的一部分:
In [26]: 100 ** (np.int64(50) - 1)
Out[26]: 0
In [27]: 100 ** (50 - 1)
Out[27]: 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
In [28]: type(100 ** (np.int64(50) - 1))
Out[28]: numpy.int64
Run Code Online (Sandbox Code Playgroud)
你看到的是int64溢出,因此取幂的结果基本上是"随机的",而python的ints具有无限的范围并给出正确的结果.
总结:
numpy和python数据类型之间进行转换,请使用正确的方法,在本例中array.tolist()numpys数据类型的范围有限,因此您应检查溢出并在其他情况下预期会出现奇怪的结果.如果您没有使用正确的转换方法,则最终可能会numpy在您没有预料到时使用数据类型(如本例所示).numpy/一个非常广泛使用的库.在这些经过充分测试和广泛使用的软件中,在这些微不足道的案例中发现错误的机会非常小.如果程序给出意想不到的结果,那么99.999%的时间是因为你做错了.因此,在责备其他人之前,请尝试逐步检查您的计划正在做什么.