Index: Python/bltinmodule.c =================================================================== --- Python/bltinmodule.c (revision 47103) +++ Python/bltinmodule.c (working copy) @@ -1622,80 +1622,6 @@ static PyObject * -builtin_reduce(PyObject *self, PyObject *args) -{ - PyObject *seq, *func, *result = NULL, *it; - - if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result)) - return NULL; - if (result != NULL) - Py_INCREF(result); - - it = PyObject_GetIter(seq); - if (it == NULL) { - PyErr_SetString(PyExc_TypeError, - "reduce() arg 2 must support iteration"); - Py_XDECREF(result); - return NULL; - } - - if ((args = PyTuple_New(2)) == NULL) - goto Fail; - - for (;;) { - PyObject *op2; - - if (args->ob_refcnt > 1) { - Py_DECREF(args); - if ((args = PyTuple_New(2)) == NULL) - goto Fail; - } - - op2 = PyIter_Next(it); - if (op2 == NULL) { - if (PyErr_Occurred()) - goto Fail; - break; - } - - if (result == NULL) - result = op2; - else { - PyTuple_SetItem(args, 0, result); - PyTuple_SetItem(args, 1, op2); - if ((result = PyEval_CallObject(func, args)) == NULL) - goto Fail; - } - } - - Py_DECREF(args); - - if (result == NULL) - PyErr_SetString(PyExc_TypeError, - "reduce() of empty sequence with no initial value"); - - Py_DECREF(it); - return result; - -Fail: - Py_XDECREF(args); - Py_XDECREF(result); - Py_DECREF(it); - return NULL; -} - -PyDoc_STRVAR(reduce_doc, -"reduce(function, sequence[, initial]) -> value\n\ -\n\ -Apply a function of two arguments cumulatively to the items of a sequence,\n\ -from left to right, so as to reduce the sequence to a single value.\n\ -For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ -((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\ -of the sequence in the calculation, and serves as a default when the\n\ -sequence is empty."); - - -static PyObject * builtin_reload(PyObject *self, PyObject *v) { return PyImport_ReloadModule(v); @@ -2096,7 +2022,6 @@ {"ord", builtin_ord, METH_O, ord_doc}, {"pow", builtin_pow, METH_VARARGS, pow_doc}, {"range", builtin_range, METH_VARARGS, range_doc}, - {"reduce", builtin_reduce, METH_VARARGS, reduce_doc}, {"reload", builtin_reload, METH_O, reload_doc}, {"repr", builtin_repr, METH_O, repr_doc}, {"round", (PyCFunction)builtin_round, METH_VARARGS | METH_KEYWORDS, round_doc}, Index: Doc/howto/doanddont.tex =================================================================== --- Doc/howto/doanddont.tex (revision 47103) +++ Doc/howto/doanddont.tex (working copy) @@ -288,20 +288,8 @@ There are also many useful builtin functions people seem not to be aware of for some reason: \function{min()} and \function{max()} can find the minimum/maximum of any sequence with comparable semantics, -for example, yet many people write they own max/min. Another highly -useful function is \function{reduce()}. Classical use of \function{reduce()} -is something like +for example, yet many people write they own max/min. -\begin{verbatim} -import sys, operator -nums = map(float, sys.argv[1:]) -print reduce(operator.add, nums)/len(nums) -\end{verbatim} - -This cute little script prints the average of all numbers given on the -command line. The \function{reduce()} adds up all the numbers, and -the rest is just some pre- and postprocessing. - On the same note, note that \function{float()}, \function{int()} and \function{long()} all accept arguments of type string, and so are suited to parsing --- assuming you are ready to deal with the Index: Doc/lib/libfuncs.tex =================================================================== --- Doc/lib/libfuncs.tex (revision 47103) +++ Doc/lib/libfuncs.tex (working copy) @@ -810,19 +810,6 @@ \end{verbatim} \end{funcdesc} -\begin{funcdesc}{reduce}{function, sequence\optional{, initializer}} - Apply \var{function} of two arguments cumulatively to the items of - \var{sequence}, from left to right, so as to reduce the sequence to - a single value. For example, \code{reduce(lambda x, y: x+y, [1, 2, - 3, 4, 5])} calculates \code{((((1+2)+3)+4)+5)}. The left argument, - \var{x}, is the accumulated value and the right argument, \var{y}, - is the update value from the \var{sequence}. If the optional - \var{initializer} is present, it is placed before the items of the - sequence in the calculation, and serves as a default when the - sequence is empty. If \var{initializer} is not given and - \var{sequence} contains only one item, the first item is returned. -\end{funcdesc} - \begin{funcdesc}{reload}{module} Reload a previously imported \var{module}. The argument must be a module object, so it must have been successfully @@ -1010,8 +997,6 @@ The \var{sequence}'s items are normally numbers, and are not allowed to be strings. The fast, correct way to concatenate sequence of strings is by calling \code{''.join(\var{sequence})}. - Note that \code{sum(range(\var{n}), \var{m})} is equivalent to - \code{reduce(operator.add, range(\var{n}), \var{m})} \versionadded{2.3} \end{funcdesc} Index: Doc/tut/tut.tex =================================================================== --- Doc/tut/tut.tex (revision 47103) +++ Doc/tut/tut.tex (working copy) @@ -1893,8 +1893,8 @@ \subsection{Functional Programming Tools \label{functional}} -There are three built-in functions that are very useful when used with -lists: \function{filter()}, \function{map()}, and \function{reduce()}. +There are two built-in functions that are very useful when used with +lists: \function{filter()} and \function{map()}. \samp{filter(\var{function}, \var{sequence})} returns a sequence consisting of those items from the @@ -1935,41 +1935,6 @@ [0, 2, 4, 6, 8, 10, 12, 14] \end{verbatim} -\samp{reduce(\var{function}, \var{sequence})} returns a single value -constructed by calling the binary function \var{function} on the first two -items of the sequence, then on the result and the next item, and so -on. For example, to compute the sum of the numbers 1 through 10: - -\begin{verbatim} ->>> def add(x,y): return x+y -... ->>> reduce(add, range(1, 11)) -55 -\end{verbatim} - -If there's only one item in the sequence, its value is returned; if -the sequence is empty, an exception is raised. - -A third argument can be passed to indicate the starting value. In this -case the starting value is returned for an empty sequence, and the -function is first applied to the starting value and the first sequence -item, then to the result and the next item, and so on. For example, - -\begin{verbatim} ->>> def sum(seq): -... def add(x,y): return x+y -... return reduce(add, seq, 0) -... ->>> sum(range(1, 11)) -55 ->>> sum([]) -0 -\end{verbatim} - -Don't use this example's definition of \function{sum()}: since summing -numbers is such a common need, a built-in function -\code{sum(\var{sequence})} is already provided, and works exactly like -this. \versionadded{2.3} \subsection{List Comprehensions} @@ -2739,7 +2704,7 @@ 'id', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', - 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', + 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] \end{verbatim} Index: Lib/difflib.py =================================================================== --- Lib/difflib.py (revision 47103) +++ Lib/difflib.py (working copy) @@ -626,8 +626,9 @@ 1.0 """ - matches = reduce(lambda sum, triple: sum + triple[-1], - self.get_matching_blocks(), 0) + matches = 0 + for triple in self.get_matching_blocks(): + matches += triple[-1] return _calculate_ratio(matches, len(self.a) + len(self.b)) def quick_ratio(self): Index: Lib/csv.py =================================================================== --- Lib/csv.py (revision 47103) +++ Lib/csv.py (working copy) @@ -20,6 +20,12 @@ "Error", "Dialect", "excel", "excel_tab", "reader", "writer", "register_dialect", "get_dialect", "list_dialects", "Sniffer", "unregister_dialect", "__version__", "DictReader", "DictWriter" ] + +def reduce(func, seq): + accu = seq[0] + for obj in seq[1:]: + accu = func(accu, obj) + return accu class Dialect: """Describe an Excel dialect. Index: Lib/test/test_iter.py =================================================================== --- Lib/test/test_iter.py (revision 47103) +++ Lib/test/test_iter.py (working copy) @@ -498,19 +498,6 @@ for y in NoGuessLen5(), Guess3Len5(), Guess30Len5(): self.assertEqual(zip(x, y), expected) - # Test reduces()'s use of iterators. - def test_builtin_reduce(self): - from operator import add - self.assertEqual(reduce(add, SequenceClass(5)), 10) - self.assertEqual(reduce(add, SequenceClass(5), 42), 52) - self.assertRaises(TypeError, reduce, add, SequenceClass(0)) - self.assertEqual(reduce(add, SequenceClass(0), 42), 42) - self.assertEqual(reduce(add, SequenceClass(1)), 0) - self.assertEqual(reduce(add, SequenceClass(1), 42), 42) - - d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(reduce(add, d), "".join(d.keys())) - # This test case will be removed if we don't have Unicode def test_unicode_join_endcase(self): Index: Lib/test/test_random.py =================================================================== --- Lib/test/test_random.py (revision 47103) +++ Lib/test/test_random.py (working copy) @@ -77,7 +77,10 @@ pop = range(n) trials = 10000 # large num prevents false negatives without slowing normal case def factorial(n): - return reduce(int.__mul__, xrange(1, n), 1) + accu = 1 + for i in xrange(1, n): + accu *= i + return accu for k in xrange(n): expected = factorial(n) // factorial(n-k) perms = {} Index: Lib/test/test_builtin.py =================================================================== --- Lib/test/test_builtin.py (revision 47103) +++ Lib/test/test_builtin.py (working copy) @@ -1380,32 +1380,6 @@ self.assertRaises(OverflowError, range, -sys.maxint, sys.maxint) self.assertRaises(OverflowError, range, 0, 2*sys.maxint) - def test_reduce(self): - self.assertEqual(reduce(lambda x, y: x+y, ['a', 'b', 'c'], ''), 'abc') - self.assertEqual( - reduce(lambda x, y: x+y, [['a', 'c'], [], ['d', 'w']], []), - ['a','c','d','w'] - ) - self.assertEqual(reduce(lambda x, y: x*y, range(2,8), 1), 5040) - self.assertEqual( - reduce(lambda x, y: x*y, range(2,21), 1L), - 2432902008176640000L - ) - self.assertEqual(reduce(lambda x, y: x+y, Squares(10)), 285) - self.assertEqual(reduce(lambda x, y: x+y, Squares(10), 0), 285) - self.assertEqual(reduce(lambda x, y: x+y, Squares(0), 0), 0) - self.assertRaises(TypeError, reduce) - self.assertRaises(TypeError, reduce, 42, 42) - self.assertRaises(TypeError, reduce, 42, 42, 42) - self.assertEqual(reduce(42, "1"), "1") # func is never called with one item - self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item - self.assertRaises(TypeError, reduce, 42, (42, 42)) - - class BadSeq: - def __getitem__(self, index): - raise ValueError - self.assertRaises(ValueError, reduce, 42, BadSeq()) - def test_reload(self): import marshal reload(marshal)