It would be nice if math.prod
supported a mod
keyword argument, similar to pow
(the built-in one, not the math
one).
The third argument to pow is not a good interface. It should have been a separate function like powmod
. It would be a mistake to extend that interface to other functions.
It is not hard to write this function yourself:
def prodmod(x: Iterable[int], mod: int) -> int:
"""prod(x) % mod"""
result = 1
for xi in x:
result = (result * xi) % mod
return result
Why? …
I think it should be equivalent to prod(x) % mod
, but yours isn’t. So maybe it’s a little bit hard.
The 3-arg pow(x,y,z)
is a very different operation from pow(x,y)
, is not defined for anything like the same kinds of inputs and has a weird ternary dispatch that doesn’t generally work. It doesn’t help anything to put these two operations in the same function with an optional argument that completely changes the behaviour.
There is a use in having functions like inv_mod(x,m)
, pow_mod(x,n,m)
, sqrt_mod(x,m)
etc but they should be distinct functions. Following that naming scheme you would even want div_mod(x,y,m)
but meaning something different from divmod
so that name clash would be confusing.
It is for reasonable inputs and was intended to be a simple demonstration. A pow_mod
function has a little more complexity to it but prod_mod
is not more complicated than the obvious loop. If you actually have a use for this function it will be for mod > 1
but feel free to handle other cases for completeness if you want.
FYI: They are planning to split out the stuff in math
that are specific to integer arithmetic. Consider how this could fit within that plan:
- A separate function in the separate module/submodule.
- Or if you plan
mod
to allow non-integers. - …
Hmm, I’ve used pow
with and without third argument and with positive and negative second argument and I think I never had a problem with it. I like it the way it is…
So many words for just mere opinions. Some, like imagining straw-meanings of “they”. My “they” only means they (third person, not me, not the OP), only that.
Have you ever used it in a situation where it was useful that it is a single function that can take either two or three arguments rather than being two separate functions?
Something like:
# args is a tuple of 2 or possibly 3 ints
# and this operation is somehow useful:
r = pow(*args)
Or perhaps more plausibly:
# mod is either None or an int
r = pow(x, n, mod)
If there was a separate function math.powmod(x,n,m)
that only works for int
would you have ever wanted pow(x,y,z)
instead? Have you ever used or wanted to use the 3-arg form with anything other than int
?
Sorry that some people here feel the need to be snarky to make a point. It is important though to distinguish between a proposal and a plan.