Home > Net >  How Python’s reduce() works? A combination of cycle on functions and reduce on list (Python, functio
How Python’s reduce() works? A combination of cycle on functions and reduce on list (Python, functio

Time:07-07

I'm learning python by my own, so I don't know anybody to ask for help or ask my dumb questions...and I come here for that. Here the problem: I trained some kata on codewars, can't solve one, so I saw the solution and I can't even get how does this code work! Of course, I read about next() and cycle(), but why they're together there...I just can't get it. Please, could you explain this code, how does it work and why does it work in this way.

from functools import reduce
from itertools import cycle

def reduce_by_rules(lst, rules):
  rs = cycle(rules)
  return reduce(lambda x, y: next(rs)(x, y), lst)

CodePudding user response:

Suppose you have two functions. The output of the example below code is 21.

Why?

At the first, x,y come from first, second elements of lst. At continue x comes from return of functions and y comes from the element of lst.

  1. x=1, y=2 -> one(1,2) -> 1 2 1 -> 4
  2. x=4, y=3 -> two(4,3) -> 4 3 2 -> 9
  3. x=9, y=4 -> one(9,4) -> 9 4 1 -> 14
  4. x=14, y=5 -> two(14,5) -> 14 5 2 -> 21 -> return
from functools import reduce
from itertools import cycle

def one(x,y):
    return x y 1
def two(x,y):
    return x y 2


rules = [one, two]
lst = [1,2,3,4,5]

def reduce_by_rules(lst, rules):
    rs = cycle(rules)
    return reduce(lambda x, y: next(rs)(x, y), lst)
    # return two(one(two(one(1,2), 3), 4), 5)


print(reduce_by_rules(lst, rules))
# 21

CodePudding user response:

cycle(rules) is just a repeating set of functions, for instance:

def multiple(x,y):
   return x*y
def divide(x,y):
   return x/y

rules = (multiple, divide)
lst = [range(100)]

def reduce_by_rules(lst, rules):
  rs = cycle(rules) # -> multiply, divide, multiply, divide, ...repeats forever
  # reduce applies the function to each number and return a number reduce(foo, [1,2,3,4]) => foo(foo(foo(1,2),3),4) 
  return reduce(lambda x, y: next(rs)(x, y), lst)

reduce_by_rules(lst, rules)

if it helps lemme define my own cycle function:

def my_cyle(lst):
   while True:
      for element in lst:
           yield element

And my own reduce:

def my_reduce(function, lst):
   res = lst[0]
   for e in lst[1:]:
       res = function(res, e)
   return res     
  • Related