Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

function that accepts any amount of arguments?

0 views
Skip to first unread message

globalrev

unread,
Apr 23, 2008, 11:43:02 PM4/23/08
to
if i want a function that can take any amount of arguments how do i
do?

lets say i want a function average that accepts any number of integers
and returns the average.

Paul McNett

unread,
Apr 23, 2008, 11:49:04 PM4/23/08
to globalrev, pytho...@python.org
globalrev wrote:
> if i want a function that can take any amount of arguments how do i
> do?

Put an asterisk before the argument name.


> lets say i want a function average that accepts any number of integers
> and returns the average.

def avg(*args):
return sum(args) / len(args)

There are some dangers (at least two glaring ones) with this code,
though, which I leave as an exercise for the reader.

:)

Paul

Steve Holden

unread,
Apr 23, 2008, 11:52:41 PM4/23/08
to pytho...@python.org

Use a parameter of the form *args - the asterisk tells the interpreter
to collect positional arguments into a tuple. Untested:

def mean(*x):
total = 0.0
for v in x:
total += v
return v/len(x)

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Terry Reedy

unread,
Apr 24, 2008, 4:41:50 AM4/24/08
to pytho...@python.org

"globalrev" <skan...@yahoo.se> wrote in message
news:4d0b5d7a-b4ff-4bb3...@w7g2000hsa.googlegroups.com...

To add to the other comments, read the ref manual section of function defs.

Ken

unread,
Apr 24, 2008, 5:19:46 AM4/24/08
to

"Steve Holden" <st...@holdenweb.com> wrote in message
news:mailman.99.12090092...@python.org...

> globalrev wrote:
>> if i want a function that can take any amount of arguments how do i
>> do?
>>
>> lets say i want a function average that accepts any number of integers
>> and returns the average.
>
> Use a parameter of the form *args - the asterisk tells the interpreter to
> collect positional arguments into a tuple. Untested:
>
> def mean(*x):
> total = 0.0
> for v in x:
> total += v
> return v/len(x)
>

think you want total/len(x) in return statement

Steve Holden

unread,
Apr 24, 2008, 7:20:57 AM4/24/08
to pytho...@python.org
Ken wrote:
> "Steve Holden" <st...@holdenweb.com> wrote in message
[...]

>> def mean(*x):
>> total = 0.0
>> for v in x:
>> total += v
>> return v/len(x)
>>
>
> think you want total/len(x) in return statement
>
Yes indeed, how glad I am I wrote "untested". I clearly wasn't pair
programming when I wrote this post ;-)

Bruno Desthuilliers

unread,
Apr 24, 2008, 7:43:25 AM4/24/08
to
Paul McNett a écrit :

>
> def avg(*args):
> return sum(args) / len(args)
>
> There are some dangers (at least two glaring ones) with this code,
> though, which I leave as an exercise for the reader.

try:
avg("toto", 42)
except TypeError, e:
print "this is the first one : %s" % e
try:
avg()
except ZeroDivisionError, e:
print "this is the second : %s" % e

As far as I'm concerned, I would not handle the first one in the avg
function - just document that avg expects numeric args.

Not quite sure what's the best thing to do in the second case - raise a
ValueError if args is empty, or silently return 0.0 - but I'd tend to
choose the first solution (Python's Zen, verses 9-11).

malkarouri

unread,
Apr 24, 2008, 8:28:12 AM4/24/08
to
On Apr 24, 12:43 pm, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalid> wrote:
[...]

> Not quite sure what's the best thing to do in the second case - raise a
> ValueError if args is empty, or silently return 0.0 - but I'd tend to
> choose the first solution (Python's Zen, verses 9-11).

What's wrong with raising ZeroDivisionError (not stopping the
exception in the first place)?

k

Jonathan Gardner

unread,
Apr 24, 2008, 1:12:59 PM4/24/08
to
On Apr 24, 5:28 am, malkarouri <malkaro...@gmail.com> wrote:
>
> What's wrong with raising ZeroDivisionError (not stopping the
> exception in the first place)?
>

Because when I use your module, call avg (or mean) without args, I
should see an error that says, "Hey, you have to pass at least one
value in!"

ZeroDivisonError doesn't mean that. It means I tried to divide by
zero. Naively, I don't see where I was dividing by zero (because I
don't remember how to calculate the mean---that's what your code was
for.)

ValueError does mean that I didn't pass the right kind of arguments
in. ValueError("No items specified") would be even clearer. (Or maybe
TypeError?)

In general, any exception thrown should be meaningful to the code you
are throwing it to. That means they aren't familiar with how your code
works.


Steve Holden

unread,
Apr 24, 2008, 1:41:34 PM4/24/08
to pytho...@python.org

This is Advice. Software Engineering's next door ;-)

bruno.des...@gmail.com

unread,
Apr 24, 2008, 3:12:06 PM4/24/08
to
On 24 avr, 14:28, malkarouri <malkaro...@gmail.com> wrote:

> On Apr 24, 12:43 pm, Bruno Desthuilliers <bruno.42.desthuilli...@websiteburo.invalid> wrote:
>
> [...]
>
> > Not quite sure what's the best thing to do in the second case - raise a
> > ValueError if args is empty, or silently return 0.0 - but I'd tend to
> > choose the first solution (Python's Zen, verses 9-11).
>
> What's wrong with raising ZeroDivisionError (not stopping the
> exception in the first place)?

Because - from a semantic POV - the real error is not that you're
trying to divide zero by zero, but that you failed to pass any
argument. FWIW, I'd personnaly write avg as taking a sequence - ie,
not using varargs - in which case calling it without arguments would a
TypeError (so BTW please s/Value/Type/ in my previous post).

member thudfoo

unread,
Apr 24, 2008, 3:13:48 PM4/24/08
to pytho...@python.org

[source]|557> def average(n, *ints):
|...> return (sum(ints)+n) / (len(ints) + 1)
|...>
[source]|558> average (1,2,3)
<558> 2
[source]|559> average(3)
<559> 3
[source]|560> average(1,2)
<560> 1
[source]|561> average(0)
<561> 0
[source]|562> average()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/usr/share/doc/packages/python-dateutil/source/<ipython console> in <module>()

TypeError: average() takes at least 1 argument (0 given)

Steve Holden

unread,
Apr 24, 2008, 3:36:16 PM4/24/08
to pytho...@python.org
member thudfoo wrote:
> On 4/24/08, Jonathan Gardner <jgar...@jonathangardner.net> wrote:
> [source]|557> def average(n, *ints):
> |...> return (sum(ints)+n) / (len(ints) + 1)
> |...>
> [source]|558> average (1,2,3)
> <558> 2
> [source]|559> average(3)
> <559> 3
> [source]|560> average(1,2)
> <560> 1
> [source]|561> average(0)
> <561> 0
> [source]|562> average()
> ---------------------------------------------------------------------------
> TypeError Traceback (most recent call last)
>
> /usr/share/doc/packages/python-dateutil/source/<ipython console> in <module>()
>
> TypeError: average() takes at least 1 argument (0 given)
> --
> http://mail.python.org/mailman/listinfo/python-list
>
It would also be usual to use floating arithmetic to ensure that the
mean of 1 and 2 was 1.5 rather than 1.

Nick Craig-Wood

unread,
Apr 25, 2008, 8:30:03 AM4/25/08
to
Steve Holden <st...@holdenweb.com> wrote:
> Ken wrote:
> > "Steve Holden" <st...@holdenweb.com> wrote in message
> [...]
> >> def mean(*x):
> >> total = 0.0
> >> for v in x:
> >> total += v
> >> return v/len(x)
> >>
> >
> > think you want total/len(x) in return statement
> >
> Yes indeed, how glad I am I wrote "untested". I clearly wasn't pair
> programming when I wrote this post ;-)

Posting to comp.lang.python is pair programming with the entire
internet ;-)


--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

Steve Holden

unread,
Apr 25, 2008, 8:55:28 AM4/25/08
to pytho...@python.org
Nick Craig-Wood wrote:
> Steve Holden <st...@holdenweb.com> wrote:
>> Ken wrote:
>>> "Steve Holden" <st...@holdenweb.com> wrote in message
>> [...]
>>>> def mean(*x):
>>>> total = 0.0
>>>> for v in x:
>>>> total += v
>>>> return v/len(x)
>>>>
>>> think you want total/len(x) in return statement
>>>
>> Yes indeed, how glad I am I wrote "untested". I clearly wasn't pair
>> programming when I wrote this post ;-)
>
> Posting to comp.lang.python is pair programming with the entire
> internet ;-)
>
>
+1 QOTW :)

Lie

unread,
Apr 26, 2008, 2:59:09 AM4/26/08
to
On Apr 25, 2:12 am, "bruno.desthuilli...@gmail.com"

The problem with passing it as a sequence is, if you want to call it,
you may have to wrestle with this odd looking code:
avg((3, 4, 6, 7))

rather than this, more natural code:
avg(3, 4, 6, 7)

And FWIW, the OP asked if it is possible to pass variable amount of
arguments, avg is just a mere example of one where it could be used
not where it could be best used.

Nick Craig-Wood wrote:
> Steve Holden <st...@holdenweb.com> wrote:
>> Ken wrote:
>>> "Steve Holden" <st...@holdenweb.com> wrote in message
>> [...]
>>>> def mean(*x):
>>>> total = 0.0
>>>> for v in x:
>>>> total += v
>>>> return v/len(x)

>>> think you want total/len(x) in return statement

>> Yes indeed, how glad I am I wrote "untested". I clearly wasn't pair
>> programming when I wrote this post ;-)

> Posting to comp.lang.python is pair programming with the entire
> internet ;-)

No, actually it's pair programming with the readers of c.l.py (or more
accurately with the readers of c.l.py that happens to pass the said
thread).

Bruno Desthuilliers

unread,
Apr 28, 2008, 9:26:20 AM4/28/08
to
Lie a écrit :

(...)

>> FWIW, I'd personnaly write avg as taking a sequence - ie,
>> not using varargs - in which case calling it without arguments would a
>> TypeError (so BTW please s/Value/Type/ in my previous post).
>
> The problem with passing it as a sequence is, if you want to call it,
> you may have to wrestle with this odd looking code:
> avg((3, 4, 6, 7))
>
> rather than this, more natural code:
> avg(3, 4, 6, 7)

Possibly. Yet my experience is that, most of the time, such a function
will be called with an already existing sequence, so the most common
call scheme is

res = avg(some_sequence)

which is more natural than

res = avg(*some_sequence)

!-)


> And FWIW, the OP asked if it is possible to pass variable amount of
> arguments, avg is just a mere example of one where it could be used
> not where it could be best used.

Indeed - but that's not what I was commenting on.

0 new messages