diff options
author | Guido van Rossum <guido@python.org> | 2006-08-22 00:21:25 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2006-08-22 00:21:25 (GMT) |
commit | 89da5d7c3d9cf5bfd4a374e23fd924bbffdeaf5c (patch) | |
tree | aef767c70a3b57c4128d44816e4e070d28fffb9d | |
parent | 6cefeb0e8156406ac3f99248f6a3d3cd1536ca23 (diff) | |
download | cpython-89da5d7c3d9cf5bfd4a374e23fd924bbffdeaf5c.zip cpython-89da5d7c3d9cf5bfd4a374e23fd924bbffdeaf5c.tar.gz cpython-89da5d7c3d9cf5bfd4a374e23fd924bbffdeaf5c.tar.bz2 |
Kill reduce(). A coproduction of John Reese, Jacques Frechet, and Alex M.
-rw-r--r-- | Lib/csv.py | 12 | ||||
-rw-r--r-- | Lib/difflib.py | 3 | ||||
-rw-r--r-- | Lib/idlelib/AutoCompleteWindow.py | 6 | ||||
-rw-r--r-- | Lib/idlelib/MultiCall.py | 22 | ||||
-rw-r--r-- | Lib/test/test_builtin.py | 26 | ||||
-rw-r--r-- | Lib/test/test_iter.py | 13 | ||||
-rw-r--r-- | Lib/test/test_random.py | 4 | ||||
-rw-r--r-- | Python/bltinmodule.c | 75 | ||||
-rwxr-xr-x | Tools/i18n/pygettext.py | 4 | ||||
-rwxr-xr-x | Tools/pybench/pybench.py | 4 |
10 files changed, 25 insertions, 144 deletions
@@ -221,12 +221,10 @@ class Sniffer: if m[n]: spaces += 1 - quotechar = reduce(lambda a, b, quotes = quotes: - (quotes[a] > quotes[b]) and a or b, quotes.keys()) + quotechar = max(quotes, key=quotes.get) if delims: - delim = reduce(lambda a, b, delims = delims: - (delims[a] > delims[b]) and a or b, delims.keys()) + delim = max(delims, key=delims.get) skipinitialspace = delims[delim] == spaces if delim == '\n': # most likely a file with a single column delim = '' @@ -285,14 +283,12 @@ class Sniffer: continue # get the mode of the frequencies if len(items) > 1: - modes[char] = reduce(lambda a, b: a[1] > b[1] and a or b, - items) + modes[char] = max(items, key=lambda x: x[1]) # adjust the mode - subtract the sum of all # other frequencies items.remove(modes[char]) modes[char] = (modes[char][0], modes[char][1] - - reduce(lambda a, b: (0, a[1] + b[1]), - items)[1]) + - sum(item[1] for item in items)) else: modes[char] = items[0] diff --git a/Lib/difflib.py b/Lib/difflib.py index 7ab682d..408079b 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -652,8 +652,7 @@ class SequenceMatcher: 1.0 """ - matches = reduce(lambda sum, triple: sum + triple[-1], - self.get_matching_blocks(), 0) + matches = sum(triple[-1] for triple in self.get_matching_blocks()) return _calculate_ratio(matches, len(self.a) + len(self.b)) def quick_ratio(self): diff --git a/Lib/idlelib/AutoCompleteWindow.py b/Lib/idlelib/AutoCompleteWindow.py index d8bbff4..8bed034 100644 --- a/Lib/idlelib/AutoCompleteWindow.py +++ b/Lib/idlelib/AutoCompleteWindow.py @@ -335,10 +335,8 @@ class AutoCompleteWindow: self.userwantswindow = True return - elif reduce(lambda x, y: x or y, - [keysym.find(s) != -1 for s in ("Shift", "Control", "Alt", - "Meta", "Command", "Option") - ]): + elif any(s in keysym for s in ("Shift", "Control", "Alt", + "Meta", "Command", "Option")): # A modifier key, so ignore return diff --git a/Lib/idlelib/MultiCall.py b/Lib/idlelib/MultiCall.py index 4f53115..1c6103a 100644 --- a/Lib/idlelib/MultiCall.py +++ b/Lib/idlelib/MultiCall.py @@ -106,24 +106,26 @@ class _SimpleBinder: # _state_subsets gives for each combination of modifiers, or *state*, # a list of the states which are a subset of it. This list is ordered by the # number of modifiers is the state - the most specific state comes first. +# XXX rewrite without overusing functional primitives :-) _states = range(1 << len(_modifiers)) -_state_names = [reduce(lambda x, y: x + y, - [_modifiers[i][0]+'-' for i in range(len(_modifiers)) - if (1 << i) & s], - "") +_state_names = [''.join(m[0]+'-' + for i, m in enumerate(_modifiers) + if (1 << i) & s) for s in _states] _state_subsets = map(lambda i: filter(lambda j: not (j & (~i)), _states), - _states) + _states) for l in _state_subsets: l.sort(lambda a, b, nummod = lambda x: len(filter(lambda i: (1<<i) & x, range(len(_modifiers)))): nummod(b) - nummod(a)) # _state_codes gives for each state, the portable code to be passed as mc_state -_state_codes = [reduce(lambda x, y: x | y, - [_modifier_masks[i] for i in range(len(_modifiers)) - if (1 << i) & s], - 0) - for s in _states] +_state_codes = [] +for s in _states: + r = 0 + for i in range(len(_modifiers)): + if (1 << i) & s: + r |= _modifier_masks[i] + _state_codes.append(r) class _ComplexBinder: # This class binds many functions, and only unbinds them when it is deleted. diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 13a5241..b0dbd4a 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1393,32 +1393,6 @@ class BuiltinTest(unittest.TestCase): 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) diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index f83de78..324eb68 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -498,19 +498,6 @@ class TestCase(unittest.TestCase): 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): diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index bba4c7c..afcf113 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -77,7 +77,9 @@ class TestBasicOps(unittest.TestCase): 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) + if n == 0: + return 1 + return n * factorial(n - 1) for k in xrange(n): expected = factorial(n) // factorial(n-k) perms = {} diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9616394..16758d7 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1598,80 +1598,6 @@ These are exactly the valid indices for a list of 4 elements."); 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); @@ -2071,7 +1997,6 @@ static PyMethodDef builtin_methods[] = { {"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}, diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index bb0dd35..eadd149 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -462,12 +462,10 @@ class TokenEater: rentries = reverse[rkey] rentries.sort() for k, v in rentries: - isdocstring = 0 # If the entry was gleaned out of a docstring, then add a # comment stating so. This is to aid translators who may wish # to skip translating some unimportant docstrings. - if reduce(operator.__add__, v.values()): - isdocstring = 1 + isdocstring = any(v.values()) # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by # file name and then by line number. diff --git a/Tools/pybench/pybench.py b/Tools/pybench/pybench.py index 7d90ba1..370175a 100755 --- a/Tools/pybench/pybench.py +++ b/Tools/pybench/pybench.py @@ -370,7 +370,7 @@ class Test: if runs == 0: return 0.0, 0.0, 0.0, 0.0 min_time = min(self.times) - total_time = reduce(operator.add, self.times, 0.0) + total_time = sum(self.times) avg_time = total_time / float(runs) operation_avg = total_time / float(runs * self.rounds @@ -570,7 +570,7 @@ class Benchmark: if runs == 0: return 0.0, 0.0 min_time = min(self.roundtimes) - total_time = reduce(operator.add, self.roundtimes, 0.0) + total_time = sum(self.roundtimes) avg_time = total_time / float(runs) max_time = max(self.roundtimes) return (min_time, avg_time, max_time) |