Python cumulative map

Is there a more pythonic way to do the following:

def mysteryFunction( it, fun, val ):
    out = []
    for x in it:
        y,val = fun(x,val)
        out.append(y)
    return out,val

where itis iterable, funis it a function that takes two inputs and returns two outputs, and valis this the initial value that the "conversion" gets on each call fun?

I ask because I regularly use map, zip, filter, reducelist-comprehension, but I cannot express the previous function as a combination of them, and it has already appeared several times. Am I missing a hidden idiom, or is it too niche to deserve it?


A specific example is the calculation of the duration in terms of (year, week, day, hour, minute, second) from a certain number of seconds:

fac = (365*24*3600, 7*24*3600, 24*3600, 3600, 60, 1)
dur,rem = mysteryFunction( fac, lambda x,y: divmod(y,x), 234567 )

dur - , rem ( , , ). , , : ( , , ); ; ; .

+4
1

itertools.accumulate. , :

def add2(x, y):
    return (x + y,) * 2 # Returning the same thing twice, new sum and accumulate sum the same

:

mysteryFunction(range(5), add2, 0)

:

([0, 1, 3, 6, 10], 10)

0 4 .

itertools.accumulate , ( ) ; :

from itertools import accumulate
from operator import add

list(accumulate(range(5), add))

list mystery_function ( list), , list,

for partialsum in accumulate(range(5), add):
    ... do stuff with partialsum ...

, accumulate, , (, , , , , accumulate), ' d , , , .

, , accumulate. , base , base 1. ( base 10):

def addless(new, base):
    return base + new, base - 1

mysteryFunction(range(5), addless, 10)

( range, base), ([10, 10, 10, 10, 10], 5). accumulate :

def addless2(last_base, new):
    _, base = last_base
    return base + new, base - 1

( , accumulate):

from itertools import accumulate, chain

base = 10

# chain used to provide initial value
accum = accumulate(chain(((None, base),), range(5)), addless2)

next(accum)   # Throw away first value that exists solely to make initial tuple

# Put the first value from each `tuple` in `out`, and keep the second value
# only for the last output, to preserve the final base
out, (*_, base) = zip(*accum)

vals (10, 10, 10, 10, 10) base 5, ( ; zip , ).

+5

Source: https://habr.com/ru/post/1694559/


All Articles