首页 > 解决方案 > 列表和迭代器之间的可能差异

问题描述

我对迭代器有一个奇怪的问题,我无法弄清楚。我有一个复杂的数值例程返回一个生成器对象(或在对代码进行一些更改之后islice)。之后我检查了结果,因为我知道结果必须有一个负虚部:

import numpy as np
threshold = 1e-8  # just check up to some numerical accuracy

results = result_generator(**inputs)
is_valid = [np.all(_result.imag < threshold) for _result in results]
print("Number of valid results: ", is_valid.count(True))

(很抱歉没有提供可执行代码,但我目前无法提出简单的代码。)现在的问题是,这会返回一个有效的解决方案。如果我将代码更改为

import numpy as np
threshold = 1e-8  # just check up to some numerical accuracy

results = list(result_generator(**inputs))
is_valid = [np.all(_result.imag < threshold) for _result in results]
print("Number of valid results: ", is_valid.count(True))

使用列表而不是生成器,我得到零有效解决方案。但是,我无法理解不同之处,因此不知道如何调试问题。如果我通过调试器并打印出带有相应索引的结果,结果甚至会有所不同,生成器之一是正确的,列表之一是错误的。


这里的数值函数:

def result_generator(z, iw, coeff, n_min, n_max):
    assert n_min >= 1
    assert n_min < n_max
    if n_min % 2:
        # index must be even
        n_min += 1

    id1 = np.ones_like(z, dtype=complex)
    A0, A1 = 0.*id1, coeff[0]*id1
    A2 = coeff[0] * id1
    B2 = 1. * id1

    multiplier = np.subtract.outer(z, iw[:-1])*coeff[1:]
    multiplier = np.moveaxis(multiplier, -1, 0).copy()

    def _iteration(multiplier_im):
        multiplier_im = multiplier_im/B2
        A2[:] = A1 + multiplier_im*A0
        B2[:] = 1. + multiplier_im

        A0[:] = A1
        A1[:] = A2 / B2
        return A1

    complete_iterations = (_iteration(multiplier_im) for multiplier_im in multiplier)
    return islice(complete_iterations, n_min, n_max, 2)

标签: pythonlistgenerator

解决方案


您一遍又一遍地产生相同的数组,而不是制作新的数组。当您调用 时list,您将获得对同一数组的引用列表,并且该数组处于其最终状态。当您不调用 时list,您会在每次产生时检查生成器产生它的状态的数组。

停止一遍又一遍地重用同一个数组。


推荐阅读