[Python-Dev] Fwd: summing a bunch of numbers (or "whatevers")
Tim Peters
tim.one@comcast.net
Mon, 21 Apr 2003 17:31:20 -0400
[Raymond Hettinger]
> For the C implementation, consider bypassing operator.add
> and calling the nb_add slot directly. It's faster and fulfills
> the intention to avoid the alternative call to sq_concat.
Checking for the existence of a (non-NULL) nb_add slot may be slicker than
special-casing strings, but I'm not sure it's ever going to work if we try
to call nb_add directly. In the end, I expect we'd have to duplicate all
the logic in abstract.c's private binary_op1() to get all the endcases
straight:
/*
Calling scheme used for binary operations:
v w Action
-------------------------------------------------------------------
new new w.op(v,w)[*], v.op(v,w), w.op(v,w)
new old v.op(v,w), coerce(v,w), v.op(v,w)
old new w.op(v,w), coerce(v,w), v.op(v,w)
old old coerce(v,w), v.op(v,w)
[*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of
v->ob_type
Legend:
-------
* new == new style number
* old == old style number
* Action indicates the order in which operations are tried until either
a valid result is produced or an error occurs.
*/
OTOH, when the nb_add slot isn't NULL, the public PyNumber_Add (the same as
operator.add) will do no more than invoke binary_op1 (unless the nb_add slot
returns NotImplemented, which is another endcase you have to consider when
calling nb_add directly -- I believe the Python core calls nb_add directly
in only one place, when it already knows that both operands are ints, and
that their sum overflows an int, so wants long.__add__ to handle it).
> Also, think about whether you want to match to two argument
> styles for min() and max():
> >>> max(1,2,3)
> 3
> >>> max([1,2,3])
> 3
Guido already Pronounced on that -- max(x, y) is the clearest way to perform
that operation, but there's no point to making sum(x, y) an obscure way to
spell x+y (I suppose you want it as a builtin synonym for operator.add,
though <wink>).
> ...
> P.S. Your new builtin works great with itertools.
> def dotproduct(vec1, vec2):
> return sum(itertools.imap(operator.mul, vec1, vec2))
Cool!