功能python - 为什么这些生成器中只有一个需要list()才能工作?

时间:2013-02-01 06:37:37

标签: python functional-programming chinese-remainder-theorem

在从元组向量(残差,模数)计算中国剩余定理时,以下代码失败:

c = ((1,5),(3,7),(11,13),(19,23))

def crt(c):
        residues, moduli = zip(*c)
        N = product(moduli)
        complements = (N/ni for ni in moduli)
        scaled_residues = (product(pair) for pair in zip(residues,complements))
        inverses = (modular_inverse(*pair) for pair in zip(complements,moduli))
        si = (product(u) for u in zip(scaled_residues,inverses))
        result = sum(si) % N
        return result

将结果赋予 0 (我猜生成的迭代是空的)。然而,以下代码完美无缺:

def crt(c):
        residues, moduli = zip(*c)
        N = product(moduli)
        complements = list((N/ni for ni in moduli)) # <-- listed
        scaled_residues = (product(pair) for pair in zip(residues,complements))
        inverses = (modular_inverse(*pair) for pair in zip(complements,moduli))
        si = (product(u) for u in zip(scaled_residues,inverses))
        result = sum(si) % N
        return result

产生(a) 8851 的正确结果。

为什么我必须list(第一台发电机之一?将list添加到任何后续生成器不会更改fail(0)结果。仅列出第一个生成器会生成正确的结果。这是怎么回事?

2 个答案:

答案 0 :(得分:6)

您在complements上重复两次。您只能在生成器表达式上迭代一次。

如果您使用的是Python 2.x,则zip(residues,complements)将使用complements并且zip(complements,moduli)没有任何内容。在Python 3.x上zip是一个生成器本身,当sum()实际运行生成器时,问题会出现在代码中。每次迭代都会从complements中提取两个项目。

答案 1 :(得分:0)

根据答案中的建议作为参考,我重新实现了问题中的代码如下:

def complements(moduli,N):
        return (N/ni for ni in moduli)

def scaled_residues(residues,complements):
        return (product(pair) for pair in zip(residues,complements))

def inverses(complements,moduli):
        return (modular_inverse(*pair) for pair in zip(complements,moduli))

def crt_residue_terms(scaled_residues,inverses):
        return (product(u) for u in zip(scaled_residues,inverses))

 def crt(c):   
    residues, moduli = zip(*c)
    N = product(moduli)
    return sum(
            crt_residue_terms(
                    scaled_residues(residues,complements(moduli,N)),
                    inverses(complements(moduli,N),moduli)
            )) % N

现在生成 8851 的正确结果,而不使用任何列表。凉。