我正在使用Python(3.3.1)构建一个模型,用于一个相当简单但非常繁琐的长期现金流合同。完整的模型在消耗的时间方面相当复杂,因此我决定尝试对其进行分析。但是,无论是否有分析,我都会得到不同的答案。
我已将代码缩减为以下示例:
def generate_cashflows( income ):
contingent_expense = [1000.0]
income_cf = [income]
outgo_cf = [ -0.001 * contingent_expense[0] ]
bank = [ income_cf[0] + outgo_cf[0] ]
for t in range(1, 20):
contingent_expense.append(1000.0)
income_cf.append( income )
outgo_cf.append( -contingent_expense[t] * 0.001 )
bank.append( bank[t-1] * (1+0.05)**(1/12)
+ income_cf[t]
+ outgo_cf[t]
)
return bank[-1]
print(str(generate_cashflows(0)))
输出:
calum@calum:~/pricing/model$ ./scratch.py
-20.793337746348953
calum@calum:~/pricing/model$ python -m cProfile scratch.py
-20.0
80 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 scratch.py:5(<module>)
1 0.000 0.000 0.000 0.000 scratch.py:5(generate_cashflows)
76 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {range}
calum@calum:~/pricing/model$
是否有一个简单的解释为什么每次输出不同的答案?我已阅读了本手册,但我没有看到任何明显的内容。
答案 0 :(得分:3)
首先,我试图用python3重现,运行“python3 scratch.py”和“python3 -m cProfile scratch.py”都在我的机器上打印-20.7933 ....
在python 2.x上返回-20.0的原因是因为divison运算符“/”在python2.x中的工作方式不同(http://legacy.python.org/dev/peps/pep-0238/)
在python2中,1/12 == 0
在python3中,1/12 == 0.08333333 ....
这意味着在python2中行
bank.append( bank[t-1] * (1+0.05)**(1/12)
简化为
bank.append( bank[t-1] * (1+0.05)**(0)
或
bank.append( bank[t-1] * 1
这可能不是你想要的。 python3解释可能是正确的,python2解释相当无用。作为旁注,将(1/12)更改为(1.0 / 12)会导致python2和python3上的输出相同,并且会使您的代码返回相同的输出,有或没有分析,但这是在处理症状而不是原因
我最好的猜测是,为什么你在使用和不使用分析时获得不同的输出是你使用python3而不进行分析,而python2使用分析。在使用和不使用分析运行代码时使用相同版本的python对于获得有意义的结果至关重要。
您使用./scratch.py的事实表明您可能有类似
的行#!/usr/bin/python3
位于scratch.py的顶部(尽管它未包含在提供的代码中)。 当你运行
./scratch.py
/ usr / bin / python3用于执行文件
运行时
python -m cProfile scratch.py
你的默认python解释器用于执行文件(我猜是python2)
如果从命令行运行“python”(没有任何其他参数),您可能会看到默认的解释器是2.X。
因此,在使用和不使用分析时,让代码返回相同的输出应该像在分析时指定python3一样简单:
python3 -m cProfile scratch.py