Working on some python koans and got one which states:

def f(a, b, z):

    """Rewrite this function to take an arbitrary number of arguments.

    It should add up all but the last argument and then subtract the
    last argument from the total.

    If no arguments are provided then return 0.
    return a + b - z

My solution:

def f(*args):
    return sum(args[:-1]) - args[-1] if args else 0

This gives 2 out of 3 stars for a solution. I am not asking for help to get 3 stars specifically, but, rather for a review of what I have, and to see if there is perhaps something I am missing, or even if you consider my solution to be good as it is.

Out of interest, I've have also tried:

    return sum(args[:-1]) - args[-1]
except IndexError:
    return 0

but that did not get 3 stars either.

What I am looking for is whether there is or isn't a more 'Pythonic' way of doing this, maybe reduce it even further than what I had there.

If there is only 1 value then the logic should give you the negative of your element.

  • \$\begingroup\$ Which site posed the challenge, and what are the criteria for evaluating the solution? \$\endgroup\$ – 200_success Oct 20 '14 at 20:52
  • 3
    \$\begingroup\$ You could do - sum(args[-1:]), though maybe that's more clever than readable. \$\endgroup\$ – xnor Oct 20 '14 at 20:56
  • \$\begingroup\$ What happens if there's exactly one arg? I don't know python too well but it looks like it might incorrectly return 0? \$\endgroup\$ – raptortech97 Oct 20 '14 at 21:43
  • \$\begingroup\$ @raptortech97 By my interpretation, f(z) should return -z, and the solutions do so correctly. \$\endgroup\$ – 200_success Oct 20 '14 at 22:11
  • \$\begingroup\$ @200_success: I wish I knew what the criteria for stars is. There is no explain on it. This is just a diversion that someone built up at work. 90 some odd challenges. \$\endgroup\$ – Kelvin Oct 22 '14 at 15:31

Using an iterator is commonly considered more Pythonic than indexing, and avoiding an if makes code more beautiful in any language:

def f(*args):
    r = reversed(args)
    return -next(r, 0) + sum(r)

Hmm I'm not sure what the requirements for 'python koans' are, but if you are getting counted off for the conditional, here are two alternatives:

  def f1(*args): return sum(list(args[:-1]) + [i*-1 for i in args[-1:]])

  def f2(*args): return sum([-i + sum(args[:-1]) for i in args[-1:]])
  • \$\begingroup\$ Hm, sadly these yielded 1 star each. Probably because of a comprehension when not necessary. \$\endgroup\$ – Kelvin Oct 22 '14 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.