【问题标题】:conditional nested for loop executing code even when condition not satisfied即使条件不满足,条件嵌套的 for 循环也会执行代码
【发布时间】:2026-01-24 04:05:01
【问题描述】:

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

如果没有约束,这个循环将因此总共执行 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>

【问题讨论】:

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


    【解决方案1】:

    这是由于在计算机硬件中将浮点数表示为以 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])
    

    【讨论】:

    • 谢谢。是的,我曾认为这也可能是一个问题,您的解决方案很优雅。