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

Cri*_*low 5 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
Run Code Online (Sandbox Code Playgroud)

将结果赋予0(我猜生成的iterables为空).但以下代码完美运行:

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
Run Code Online (Sandbox Code Playgroud)

得出(a)8851的正确结果.

我为什么要去list(第一台发电机?添加list到任何后续生成器不会更改fail(0)结果.仅列出第一个生成器会生成正确的结果.这里发生了什么 ?

Jan*_*ila 6

你迭代两次complements.您只能在生成器表达式上迭代一次.

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