Functional python - why only one of these generators requires list () to work?

When calculating the Chinese stop theorem from the tuple vector (deduction, module), the following code is not executed:

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

Give the result as 0 (I think the generated iterations are empty). However, the following code works fine:

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

Which gives (a) the correct result 8851 .

Why do I need list(one of the first generators? Adding listto any subsequent generator does not change the result of fail (0). Only the output of this first generator gives the correct result. What's going on here?

+5
source share
2 answers

complements. .

Python 2.x, zip(residues,complements) complements, zip(complements,moduli) . Python 3.x zip , , sum() . complements .

+6

, , :

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 - . .

0

All Articles