Small changes to map() and filter():

(1) If a sequence S is shorter than len(S) indicated, don't fail --
just use the shorter size.  (I.e, len(S) is just a hint.)

(2) Implement the special case map(None, S) as list(S) -- it's faster.
This commit is contained in:
Guido van Rossum 1998-07-10 17:37:30 +00:00
parent bfc725bf64
commit fa4ac71dd6
1 changed files with 8 additions and 5 deletions

View File

@ -190,8 +190,6 @@ builtin_filter(self, args)
int ok; int ok;
if ((item = (*sqf->sq_item)(seq, i)) == NULL) { if ((item = (*sqf->sq_item)(seq, i)) == NULL) {
if (i < len)
goto Fail_1;
if (PyErr_ExceptionMatches(PyExc_IndexError)) { if (PyErr_ExceptionMatches(PyExc_IndexError)) {
PyErr_Clear(); PyErr_Clear();
break; break;
@ -784,6 +782,11 @@ builtin_map(self, args)
func = PyTuple_GetItem(args, 0); func = PyTuple_GetItem(args, 0);
n--; n--;
if (func == Py_None && n == 1) {
/* map(None, S) is the same as list(S). */
return PySequence_List(PyTuple_GetItem(args, 1));
}
if ((seqs = PyMem_NEW(sequence, n)) == NULL) { if ((seqs = PyMem_NEW(sequence, n)) == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
goto Fail_2; goto Fail_2;
@ -820,7 +823,6 @@ builtin_map(self, args)
if ((result = (PyObject *) PyList_New(len)) == NULL) if ((result = (PyObject *) PyList_New(len)) == NULL)
goto Fail_2; goto Fail_2;
/* XXX Special case map(None, single_list) could be more efficient */
for (i = 0; ; ++i) { for (i = 0; ; ++i) {
PyObject *alist, *item=NULL, *value; PyObject *alist, *item=NULL, *value;
int any = 0; int any = 0;
@ -840,8 +842,6 @@ builtin_map(self, args)
else { else {
item = (*sqp->sqf->sq_item)(sqp->seq, i); item = (*sqp->sqf->sq_item)(sqp->seq, i);
if (item == NULL) { if (item == NULL) {
if (i < sqp->len)
goto Fail_0;
if (PyErr_ExceptionMatches( if (PyErr_ExceptionMatches(
PyExc_IndexError)) PyExc_IndexError))
{ {
@ -897,6 +897,9 @@ builtin_map(self, args)
} }
} }
if (i < len && PyList_SetSlice(result, i, len, NULL) < 0)
goto Fail_1;
PyMem_DEL(seqs); PyMem_DEL(seqs);
return result; return result;