New submission from Ryan Freckleton:

This is a patch to implement a product() builtin function. It works
behaves similarly to reduce(operator.mul,...) but is implemented in C.

Tests and documentation are included in this patch.

----------
components: Documentation, Library (Lib), Tests
files: product_function.diff
messages: 55599
nosy: ryan.freckleton
severity: normal
status: open
title: product function patch
type: behavior
versions: Python 2.6

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1093>
__________________________________
Index: Python/bltinmodule.c
===================================================================
--- Python/bltinmodule.c	(revision 57913)
+++ Python/bltinmodule.c	(working copy)
@@ -2094,7 +2094,59 @@
 of parameter 'start' (which defaults to 0).  When the sequence is\n\
 empty, returns start.");
 
+static PyObject*
+builtin_product(PyObject *self, PyObject *args)
+{
+	PyObject *seq;
+	PyObject *result = NULL;
+	PyObject *temp, *item, *iter;
 
+	if (!PyArg_UnpackTuple(args, "product", 1, 2, &seq, &result))
+		return NULL;
+
+	iter = PyObject_GetIter(seq);
+	if (iter == NULL)
+		return NULL;
+
+	if (result == NULL) {
+		result = PyInt_FromLong(1);
+		if (result == NULL) {
+			Py_DECREF(iter);
+			return NULL;
+		}
+	} else {
+		Py_INCREF(result);
+	}
+
+	for(;;) {
+		item = PyIter_Next(iter);
+		if (item == NULL) {
+			/* error, or end-of-sequence */
+			if (PyErr_Occurred()) {
+				Py_DECREF(result);
+				result = NULL;
+			}
+			break;
+		}
+		temp = PyNumber_Multiply(result, item);
+		Py_DECREF(result);
+		Py_DECREF(item);
+		result = temp;
+		if (result == NULL)
+			break;
+	}
+	Py_DECREF(iter);
+	return result;
+}
+
+PyDoc_STRVAR(product_doc,
+"product(sequence[, start]) -> value\n\
+\n\
+Returns the product of a sequence of numbers times the value\n\
+of parameter 'start' (which defaults to 1).  When the sequence is\n\
+empty, returns start.");
+
+
 static PyObject *
 builtin_isinstance(PyObject *self, PyObject *args)
 {
@@ -2296,6 +2348,7 @@
  	{"open",	(PyCFunction)builtin_open,       METH_VARARGS | METH_KEYWORDS, open_doc},
  	{"ord",		builtin_ord,        METH_O, ord_doc},
  	{"pow",		builtin_pow,        METH_VARARGS, pow_doc},
+ 	{"product",	builtin_product,    METH_VARARGS, product_doc},
  	{"range",	builtin_range,      METH_VARARGS, range_doc},
  	{"raw_input",	builtin_raw_input,  METH_VARARGS, raw_input_doc},
  	{"reduce",	builtin_reduce,     METH_VARARGS, reduce_doc},
Index: Doc/library/functions.rst
===================================================================
--- Doc/library/functions.rst	(revision 57913)
+++ Doc/library/functions.rst	(working copy)
@@ -1104,7 +1104,15 @@
 
    .. versionadded:: 2.3
 
+.. function:: product(iterable[, start])
+   Multiplies *start* and the items of an *iterable* from left to right and
+   returns the product. *start* defaults to ``1``. The *iterable*'s items are
+   normally numbers. Note that ``product(range(n), m)`` is equivalent to
+   ``reduce(operator.mul, range(n), m)``
 
+   .. versionadded:: 2.6
+
+
 .. function:: super(type[, object-or-type])
 
    Return the superclass of *type*.  If the second argument is omitted the super
Index: Lib/test/test_builtin.py
===================================================================
--- Lib/test/test_builtin.py	(revision 57913)
+++ Lib/test/test_builtin.py	(working copy)
@@ -1697,6 +1697,19 @@
                 raise ValueError
         self.assertRaises(ValueError, sum, BadSeq())
 
+    def test_product(self):
+        self.assertEqual(product([]), 1)
+        self.assertEqual(product(range(2,8)), 5040)
+        self.assertEqual(product(iter(range(2,8))), 5040)
+
+        self.assertRaises(TypeError, product)
+        self.assertRaises(TypeError, product, 42)
+        self.assertRaises(TypeError, product, ['a', 'b', 'c'])
+        self.assertRaises(TypeError, product, ['a', 'b', 'c'], '')
+        self.assertRaises(TypeError, product, [[1], [2], [3]])
+        self.assertRaises(TypeError, product, [{2:3}])
+        self.assertRaises(TypeError, product, [{2:3}]*2, {2:3})
+
     def test_tuple(self):
         self.assertEqual(tuple(()), ())
         t0_3 = (0, 1, 2, 3)
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to