Kill reduce(). A coproduction of John Reese, Jacques Frechet, and Alex M.
This commit is contained in:
parent
6cefeb0e81
commit
89da5d7c3d
12
Lib/csv.py
12
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]
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -1597,80 +1597,6 @@ For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!\n\
|
|||
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)
|
||||
{
|
||||
|
@ -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},
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue