[Python-Dev] identity operands (was python-dev Summary for 2005-03-01 through 2005-03-15 [draft])

Nick Coghlan ncoghlan at iinet.net.au
Sun Mar 20 02:47:44 CET 2005


Kurt B. Kaiser wrote:
> Nick Coghlan <ncoghlan at iinet.net.au> writes:
>>This is fairly abusive of sum, though :)
> 
[snip Kurt's timings]

Even avoiding the object instantiation doesn't help much:

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Py> setup = """\
... class additive_identity(object):
...   def __add__(self, other):
...     return other
...
... ai = additive_identity()
... """
Py> t = timeit.Timer("sum(('a', 'bcd', 'e'), ai)", setup)
Py> t.repeat()
[1.7930380266773089, 1.7397206526577538, 1.7193376076378759]
Py> t = timeit.Timer("''.join(('a', 'bcd', 'e'))")
Py> t.repeat()
[0.58006451058344055, 0.58431742467269032, 0.5788117914319173]
Py> t = timeit.Timer("'a' + 'bcd' + 'e'")
Py> t.repeat()
[0.29404383490157215, 0.29554694930084224, 0.29612594514117063]

(I almost forgot to repeat your other tests to account for the differences in 
machine speed!)

So, using "".join is roughly three times as fast as abusing sum :)

I'm still intrigued by the concept of providing an object or objects (e.g. in 
operator) that work as an identity operand for all cases where it makes sense:

Commutative operations (always return 'other'):
__add__(self, other)
__radd__(self, other)
__mul__(self, other)
__rmul__(self, other)
__xor__(self, other)
__rxor__(self, other)
__and__(self, other)
__rand__(self, other)
__or__(self, other)
__ror__(self, other)

Non-commutative operations with identity on the right (return 'other')
__rsub__(self, other)
__rdiv__(self, other)
__rtruediv__(self, other)
__rfloordiv__(self, other)
__rmod__(self, other)
__rdivmod__(self, other)
__rpow__(self, other)
__rlshift__(self, other)
__rrshift__(self, other)

Other non-commutative operations with a sensible identity:
__sub__(self, other):  return -other

Non-commutative operations without a sensible identity:
__div__(self, other)
__truediv__(self, other)
__floordiv__(self, other)
__mod__(self, other)
__divmod__(self, other)
__pow__(self, other[, modulo])
__lshift__(self, other)
__rshift__(self, other)

If it was done, it would probably be best to do this as at least two objects - 
one for which bool(additive_identity) evaluates to False, and the other for 
which bool(multiplicative_identity) evaluates to True.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net


More information about the Python-Dev mailing list