0

I have a python2 code that I used before but I would like replace reduce by a loop. How can I rewrite this part prod = reduce(lambda a, b: a * b, n) function below?

def chineeseRemainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a * b, n)

    for n_i, a_i in zip(n, a):
        p = prod // n_i
        sum += a_i * Get_Multi_Inv(p, n_i) * p
    return sum % prod
7
  • I am trying not to import the functools library Commented Nov 2, 2018 at 3:33
  • You can also see a possible reduce implementation in the docs. It's probably a bit more cautious than your implementation would need to be, but it will give you an idea. Commented Nov 2, 2018 at 3:39
  • Thanks for pointing that out. I was looking at it but I was able to understand what to use iterable, initializer=None based on my function above.. I guess, i can have function as lambda a,b:a*b but what to putt for iterable, initializer=None.. Commented Nov 2, 2018 at 3:50
  • def reduce(lambda a,b:a*b, n, initializer=None): it = iter(iterable) if initializer is None: value = next(it) else: value = initializer for element in it: value = function(value, element) return value Commented Nov 2, 2018 at 3:51
  • 1
    cool but bear in mind that if you were just gong to copy the code from functools then you may as well just use functools. As long as you really understand what that code is doing then its all good. Commented Nov 2, 2018 at 4:09

3 Answers 3

1

In general for a reduce() without a starting value, you can use iter and next to convert it to a for loop. This combination lets you use the first element of the iterable as the starting accumulator value, and loop over the rest.

iterator = iter(n)
prod = next(iterator)
for x in iterator:
    prod *= x

But in the specific case of multiplication, we know the identity element is 1, so we can use that as the starting value and multiply the whole iterable.

prod = 1
for x in n:
    prod *= x

Not all functions will have an identity like this, but many do, like 0 for + and math.inf for min(), etc.

Sign up to request clarification or add additional context in comments.

Comments

1

you can also add import

from functools import reduce

Comments

1

I have it working.

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

and I called it the function above with

prod = reduce(function1, n)

1 Comment

If you're going to make a generic reduce function, why not use the one builtin? You can use six as a compatibility layer. The benefit of not using reduce is readability (and possibly one less func call); this solution eschews both of those benefits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.