2

I want to write a python function my_sum that extends python's built-in sum in the following way:

  • If a sequence is passed to my_sum it behaves like the built-in sum.
  • If multiple values are passed to my_sum, it returns the sum of the values.

Desired output:

my_sum([1, 2, 3])  # shall return 6 (similiar to built-in sum)
my_sum(1, 2, 3)    # shall return 6 as well, (sum throws TypeError)

What worked was the following.

def my_sum(*x):
    try:
        return sum(x)  # sums multiple values
    except TypeError:
        return sum(*x)  # sums sequence of values

Is that the pythonic way to accomplish the desired behavior? For me the code looks odd.

Alex G
  • 663
  • 3
  • 13

2 Answers2

2

It is pythonic. I think at least one check is required and python has the philosophy "Ask for forgiveness not permission" (explained here) which basically means that using try-except blocks is OK for standard control flows.

If importing an established library is pythonic and something you are allowed and willing to do, you can use numpy.sum too, as follows:

import numpy as np
def my_sum(*x):
    return np.sum(x)

With this definition, both

my_sum([1, 2, 3])  
my_sum(1, 2, 3) 

return 6.

dataista
  • 3,187
  • 1
  • 16
  • 23
0

I think it is not an use case for exceptions, exceptions are for exceptional cases. Use another function if you convert arguments to a list and pass to the adder function.

In addition, the validation and formatting of the input should be in the outer part of the code, not in the final function. In the best case the data should be validated before coming to this function, and you should only have the sum function to deal with the cooked data.

It's a way to:

  • Keep things simple
  • Avoid adding conditional paths
  • Avoid defensive programming in inner code
  • And thus avoid future problems.

I would have the following code.

def argsToList(*x):
  return list(x)  

print sum([1,2,3,4])
print sum(argsToList(1,2,3,4))
# both output 10
David Lemon
  • 1,560
  • 10
  • 21