3

Why the results are different after I import NumPy?

print(sum(range(5),-1))

the answer is 9

from numpy import *
print(sum(range(5),-1))

the answer is 10

Georgy
  • 12,464
  • 7
  • 65
  • 73
everfight
  • 420
  • 3
  • 10
  • 3
    After importing everything from `numpy`, `sum` becomes `numpy.sum`. `numpy.sum`'s second argument (i.e. -1 in your case) is understood as `axis`, not another element to do `sum` – Chris Aug 20 '19 at 06:21
  • 2
    Possible duplicate of [Python's sum vs. NumPy's numpy.sum](https://stackoverflow.com/questions/10922231/pythons-sum-vs-numpys-numpy-sum) – bharatk Aug 20 '19 at 06:22
  • Your question should be "way `numpy.sum` returns a result different from built-in's `sum`? The fact that you import stuff isn't really relevant. – Bakuriu Aug 20 '19 at 06:22
  • 1
    And this is why the [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/#imports) says: "Wildcard imports (`from import *`) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools." – Matthias Aug 20 '19 at 06:31

3 Answers3

4

In-built functions should be overridden with caution.

import * can be dangerous.

The built-in sum and the sum defined in numpy serve different purposes - hence the different answers.

Help on built-in function sum in module __builtin__:

sum(...)
    sum(iterable[, start]) -> value

    Return the sum of an iterable or sequence of numbers (NOT strings)
    plus the value of 'start' (which defaults to 0).  When the sequence is
    empty, return start.
(END)


>>> import numpy
>>> help(numpy.sum)
Help on function sum in module numpy.core.fromnumeric:

sum(a, axis=None, dtype=None, out=None, keepdims=<class numpy._globals._NoValue>)
    Sum of array elements over a given axis.

    Parameters
    ----------
    a : array_like
        Elements to sum.
    axis : None or int or tuple of ints, optional
        Axis or axes along which a sum is performed.  The default,
        axis=None, will sum all of the elements of the input array.  If
        axis is negative it counts from the last to the first axis.

        .. versionadded:: 1.7.0

        If axis is a tuple of ints, a sum is performed on all of the axes
        specified in the tuple instead of a single axis or all the axes as
        before.
    dtype : dtype, optional
        The type of the returned array and of the accumulator in which the
        elements are summed.  The dtype of `a` is used by default unless `a`
        has an integer dtype of less precision than the default platform
        integer.  In that case, if `a` is signed then the platform integer
        is used while if `a` is unsigned then an unsigned integer of the
        same precision as the platform integer is used.
    out : ndarray, optional
        Alternative output array in which to place the result. It must have
        the same shape as the expected output, but the type of the output
        values will be cast if necessary.
    keepdims : bool, optional
        If this is set to True, the axes which are reduced are left
        in the result as dimensions with size one. With this option,
        the result will broadcast correctly against the input array.

        If the default value is passed, then `keepdims` will not be
        passed through to the `sum` method of sub-classes of
        `ndarray`, however any non-default value will be.  If the
        sub-classes `sum` method does not implement `keepdims` any
        exceptions will be raised.

    Returns
    -------
    sum_along_axis : ndarray
        An array with the same shape as `a`, with the specified
        axis removed.   If `a` is a 0-d array, or if `axis` is None, a scalar
        is returned.  If an output array is specified, a reference to
        `out` is returned.

    See Also
    .
    .
    .

>>>
Sharad
  • 9,282
  • 3
  • 19
  • 36
2

This happens because the builtin python sum function is overwritten with numpy.sum.

When you evaluate the builtin python sum(range(5),-1), it evaluates to something like -1 + sum([0,1,2,3,4]).

By contrast, numpy.sum assumes that -1 is the axis argument, denoting the last (and only) axis of the input array. So, you effectively get np.sum(range(5)).

hilberts_drinking_problem
  • 11,322
  • 3
  • 22
  • 51
1

This is because the second argument in numpy.sum is the axis argument, as per the documentation. Since the input is a 1d-array, sum(range(5), -1) sums along the last (and only) axis, thus being equivalent to sum(range(5)), which equals 10.

In the standard lib's sum(), the second argument is the initial value of the sum, which defaults to 0.

So your code is equivalent to -1 + sum(range(5)), which equals 9.

maahl
  • 547
  • 3
  • 17