summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2006-08-22 00:21:25 (GMT)
committerGuido van Rossum <guido@python.org>2006-08-22 00:21:25 (GMT)
commit89da5d7c3d9cf5bfd4a374e23fd924bbffdeaf5c (patch)
treeaef767c70a3b57c4128d44816e4e070d28fffb9d
parent6cefeb0e8156406ac3f99248f6a3d3cd1536ca23 (diff)
downloadcpython-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.py12
-rw-r--r--Lib/difflib.py3
-rw-r--r--Lib/idlelib/AutoCompleteWindow.py6
-rw-r--r--Lib/idlelib/MultiCall.py22
-rw-r--r--Lib/test/test_builtin.py26
-rw-r--r--Lib/test/test_iter.py13
-rw-r--r--Lib/test/test_random.py4
-rw-r--r--Python/bltinmodule.c75
-rwxr-xr-xTools/i18n/pygettext.py4
-rwxr-xr-xTools/pybench/pybench.py4
10 files changed, 25 insertions, 144 deletions
diff --git a/Lib/csv.py b/Lib/csv.py
index f213854..79d72b6 100644
--- a/Lib/csv.py
+++ b/Lib/csv.py
@@ -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)