A "Python with Numpy" programmer who decides to not use the built-in factorial function would think:
>>> from numpy import np
>>> np.multiply.reduce(np.arange(1, 10+1))
3628800
That same programmer would (hopefully) also be aware that the function will overflow for large-enough values, and might instead write it at: >>> np.multiply.reduce(np.arange(1, 1000+1, dtype=np.object))