即使条件不满足,条件嵌套for循环执行代码

时间:2016-05-19 09:11:25

标签: python if-statement for-loop nested-loops

我有一个嵌套循环结构,通过改变4个变量,oq,aq,lev和val的值来生成大量的backtests。我们的想法是在所提供的范围内执行以下变量的每个组合。

没有约束,这个循环因此将执行总共5 * 6 * 5 * 5 = 750次,其中每次约5-10秒需要几个小时。但是,存在一个约束,即所有权重必须总和为1(tot_wgt)。通过添加if语句,我希望简单地丢弃这些情况。

if (tot_wgt != 1):
    continue

不幸的是,当tot_wgt没有值为1时,代码似乎仍然执行。这似乎每次val循环完成一个循环时都会发生(并且可能在其他3个循环中的每个循环完成时也会发生)周期)。

问题解决了:我有一个缩进错误:我需要处于if语句的级别。但是看看浮点数识别的优秀答案。

mom = 0
for oq in [0.3, 0.4, 0.5, 0.6, 0.7]:
    for aq in [0.05, 0.1, 0.15, 0.2, 0.25, 0.3]:
        for lev in [0.0, 0.05, 0.1, 0.15, 0.2]:
            for val in [0.0, 0.05, 0.1, 0.15, 0.2]:

                tot_wgt = oq + aq + lev + val + mom

                if (tot_wgt != 1): #we only want to backtest where the weights add up to 1.  If <1 or >1, simply skip
                    continue


<MAIN BACKTEST CODE HERE>

1 个答案:

答案 0 :(得分:4)

这是由于将计算机硬件中的浮点数表示为基数2(二进制)分数的限制。有关详细说明,请参阅Floating Point Arithmetic: Issues and Limitations

例如,在您的情况下,

>>> 0.7 + 0.2 + 0.0 + 0.1 + 0
0.9999999999999999

# more specific
>>> from decimal import Decimal
>>> Decimal(0.7 + 0.2 + 0.0 + 0.1 + 0)
Decimal('0.99999999999999988897769753748434595763683319091796875')

正如您所看到的,这与1并不相同。解决此问题的一种简单方法就是将行if (tot_wgt != 1):替换为

if abs(tot_wgt - 1) < 0.0001 : 

Python 3.5添加了math.isclose来测试近似相等性。对于早期版本,等效函数如下。

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

使用numpy.isclose来测试两个数组在容差范围内是否在元素方面相等。

# Usage
numpy.isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)

# An example
>>> import numpy as np
>>> np.isclose([1e10,1e-7], [1.00001e10,1e-8])
array([True, False])