[Python-3000] what do I use in place of reduce?

"Martin v. Löwis" martin at v.loewis.de
Thu Apr 24 07:40:24 CEST 2008


>     >  > >>> time=1901248
>     >  > >>> reduce(lambda a, b: a[:-1] + [a[-1]%b,
>     math.floor(a[-1]/b)], [[time],
>     >  > 60, 60, 24])
>     >  >  [28, 7.0, 0.0, 22.0] # secs, mins, hrs, days
>     >
>     >  I recommend learning how to use a good old for-loop. That example is
>     >  as cryptic as can be. It's also inefficient due to calling a function
>     >  for each iteration.
> 
>     I normally frown on "me too" posts, but this time I won't refrain from
>     a loud "hear, hear!". "Clever" code is NOT a culturally positive trait
>     in the Python community (differently from most language communities...
>     and this is in fact one reason I love Python).
> 
>     Alex
> 
> 
> It wasn't only posted to be cryptic, it's one thing that's difficult to
> write with a for loop without a lot of verbosity (at least I couldn't
> figure out how to do it...).

In this case, I wouldn't use a loop at all:

py> time=1901248
py> minutes,seconds = divmod(time, 60)
py> hours,minutes = divmod(minutes, 60)
py> days,hours = divmod(hours,24)
py> seconds,minutes,hours,days
(28, 7, 0, 22)

If you absolutely want to use a loop (because you have a variable
list of divisors), write

py> time=1901248
py> div = time
py> res = []
py> for divisor in (60,60,24):
...     div, mod = divmod(div, divisor)
...     res.append(mod)
... else:
...     res.append(div)
...
py> res
[28, 7, 0, 22]

If you think this shows a lot of verbosity, please reconsider.
It's not verbose. If you absolutely want it in a single
expression, I'd write

py> time % 60, time//60%60, time//3600%24, time//(3600*24)
(28, 7, 0, 22)

Regards,
Martin

P.S. I'm not sure why you had been using floating point
operations.


More information about the Python-3000 mailing list