Current use of addition in Python

Summary: This thread is for recording current use of addition in Python. This post covers the built-in types. I'll do Counter and numpy.array in another post. Please use another thread to discuss possible possible future use of addition. BACKGROUND At present constructions such as {'a': 1} + {'b': 2} produce TypeError: unsupported operand type(s) for +: 'dict' and 'dict' Elsewhere on this list, we're discussing whether to extend dict so that it supports such constructions, and if so what semantics to give to addition of dictionaries. In this thread I intend to record the CURRENT use of addition in Python, in a neutral manner. (However, I will focus on what might be called the mathematical properties of addition in Python.) BUILT-IN TYPES In this post I talk about the exiting built-in types: see https://docs.python.org/3/library/stdtypes.html The NUMERIC types support addition, which has the following properties Commutative: a + b == b + a Associative: (a + b) + c == a + (b + c) Left-cancellation: if (a + b) == (a + c): assert b == c Right-cancellation: if (a + b) == (c + b): assert a == c Existence of zero (depending on type): zero + a == a + zero == a Multiplication by non-negative integer: a + a + .... + a == a * n == n * a Note: For floats, the equalities are ideal. For example, sometimes huge + tiny == huge + zero and so we don't exactly have cancellation. The SEQUENCE types (except range) have the following properties Associative Left-cancellation Right-cancellation Existence of zero Multiplication by non-negative integer. Note: Even though range is a sequence type, range(3) + range(3) produces TypeError: unsupported operand type(s) for +: 'range' and 'range' By the way, although documented, I find this a bit surprising: >>> (0, 1, 2) * (-1) == () True I'd have expected a ValueError. As things stand seq * (-1) * (-1) is not associative. And (-1) * seq == -seq is not true, although the left hand side is defined. CONCLUSION I've recorded the behaviour of addition for the built-in types. I'll do Counter and numpy.array in another post, later today. Please use another thread to discuss possible future use of addition. My aim in this thread is to establish and record the present use, to better support discussion of future use. -- Jonathan

Because of the current discussion of dict + dict. I think this is helping answer the question: is there anything currently in python that’s a similar usage of “+”? Personally, I don’t think it matters much, but it’s interesting. If the requirement were for new usages of “+” to be like old ones, would we have added str + str? Eric

First, I thank Rhodri for his question, and Eric for his reply (see earlier messages in this thread). SUMMARY I record the addition properties of collections.Counter and numpy.array. Finally, some comments about len(), and a promise of more tomorrow. COUNTER Now for collections.Counter -- this is "provided to support convenient and rapid tallies." https://docs.python.org/3/library/collections.html#collections.Counter In my previous post, I noted that the built-in numeric types have the properties: Commutative Associative Left and right cancellation Existence of zero Multiplication by a non-negative integer Instances of Counter 'usually' have all of these properties, except for multiplication by a non-negative integer. Here's an example where cancellation fails >>> Counter(a=-1) + Counter() Counter() Here's two more examples:
Here's an example of associativity failing: >>> (Counter(a=+1) + Counter(a=-2)) + Counter(a=2) Counter({'a': 2}) >>> Counter(a=+1) + (Counter(a=-2) + Counter(a=2)) Counter({'a': 1}) The Python docs (URL above) notes that the Counter "methods are designed only for use cases with positive values." NUMPY.ARRAY These arrays have all the properties listed above (commutative, associative, left and right cancellation, multiplication by non-negative integer), provided all the arrays have the same shape. (The shape of an array is a tuple of non-negative integers.) And for numpy.array, the zero must also have the same shape. Briefly, a numpy array acts like a multi-dimensional vector. Here's an example: >>> array(range(3)), array(range(3, 6)) (array([0, 1, 2]), array([3, 4, 5])) >>> array(range(3)) + array(range(3, 6)) array([3, 5, 7]) Here's another example: >>> array(range(3, 6)) * 4 array([12, 16, 20]) >>> 4 * array(range(3, 6)) array([12, 16, 20]) LENGTH -- len() The numeric types don't have a length: >>> len(0) TypeError: object of type 'int' has no len() The sequence and mapping types (such as list, tuple, str, bytes, set, dict) are iterable, and have a length. Also, numpy.array and collections.Counter have a length. More on length tomorrow. -- Jonathan

Because of the current discussion of dict + dict. I think this is helping answer the question: is there anything currently in python that’s a similar usage of “+”? Personally, I don’t think it matters much, but it’s interesting. If the requirement were for new usages of “+” to be like old ones, would we have added str + str? Eric

First, I thank Rhodri for his question, and Eric for his reply (see earlier messages in this thread). SUMMARY I record the addition properties of collections.Counter and numpy.array. Finally, some comments about len(), and a promise of more tomorrow. COUNTER Now for collections.Counter -- this is "provided to support convenient and rapid tallies." https://docs.python.org/3/library/collections.html#collections.Counter In my previous post, I noted that the built-in numeric types have the properties: Commutative Associative Left and right cancellation Existence of zero Multiplication by a non-negative integer Instances of Counter 'usually' have all of these properties, except for multiplication by a non-negative integer. Here's an example where cancellation fails >>> Counter(a=-1) + Counter() Counter() Here's two more examples:
Here's an example of associativity failing: >>> (Counter(a=+1) + Counter(a=-2)) + Counter(a=2) Counter({'a': 2}) >>> Counter(a=+1) + (Counter(a=-2) + Counter(a=2)) Counter({'a': 1}) The Python docs (URL above) notes that the Counter "methods are designed only for use cases with positive values." NUMPY.ARRAY These arrays have all the properties listed above (commutative, associative, left and right cancellation, multiplication by non-negative integer), provided all the arrays have the same shape. (The shape of an array is a tuple of non-negative integers.) And for numpy.array, the zero must also have the same shape. Briefly, a numpy array acts like a multi-dimensional vector. Here's an example: >>> array(range(3)), array(range(3, 6)) (array([0, 1, 2]), array([3, 4, 5])) >>> array(range(3)) + array(range(3, 6)) array([3, 5, 7]) Here's another example: >>> array(range(3, 6)) * 4 array([12, 16, 20]) >>> 4 * array(range(3, 6)) array([12, 16, 20]) LENGTH -- len() The numeric types don't have a length: >>> len(0) TypeError: object of type 'int' has no len() The sequence and mapping types (such as list, tuple, str, bytes, set, dict) are iterable, and have a length. Also, numpy.array and collections.Counter have a length. More on length tomorrow. -- Jonathan
participants (3)
-
Eric V. Smith
-
Jonathan Fine
-
Rhodri James