]> granicus.if.org Git - python/commitdiff
Issue 2186 and 2187. Move filter from itertools to builtins.
authorRaymond Hettinger <python@rcn.com>
Thu, 13 Mar 2008 00:19:26 +0000 (00:19 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 13 Mar 2008 00:19:26 +0000 (00:19 +0000)
Doc/library/itertools.rst
Lib/filecmp.py
Lib/test/test_itertools.py
Modules/itertoolsmodule.c
Python/bltinmodule.c

index 0d74c598e38fd6f99258fafdff7a240917812600..368e40d77c865d2ed1c861d22479ef2d002b4c5e 100644 (file)
@@ -234,21 +234,6 @@ loops that truncate the stream.
                   self.currkey = self.keyfunc(self.currvalue)
 
 
-.. function:: ifilter(predicate, iterable)
-
-   Make an iterator that filters elements from iterable returning only those for
-   which the predicate is ``True``. If *predicate* is ``None``, return the items
-   that are true.  This function is the same as the built-in :func:`filter`
-   function.  Equivalent to::
-
-      def ifilter(predicate, iterable):
-          if predicate is None:
-              predicate = bool
-          for x in iterable:
-              if predicate(x):
-                  yield x
-
-
 .. function:: ifilterfalse(predicate, iterable)
 
    Make an iterator that filters elements from iterable returning only those for
@@ -606,13 +591,13 @@ which incur interpreter overhead. ::
 
    def any(seq, pred=None):
        "Returns True if pred(x) is true for at least one element in the iterable"
-       for elem in ifilter(pred, seq):
+       for elem in filter(pred, seq):
            return True
        return False
 
    def no(seq, pred=None):
        "Returns True if pred(x) is false for every element in the iterable"
-       for elem in ifilter(pred, seq):
+       for elem in filter(pred, seq):
            return False
        return True
 
index 12ba3ef6c16a00eabd88541b0e3c44993d2d7725..14e1eb4b8514f38442b2653a6e6be93b2f5e658a 100644 (file)
@@ -12,7 +12,7 @@ Functions:
 import os
 import stat
 import warnings
-from itertools import ifilter, ifilterfalse, imap, izip
+from itertools import ifilterfalse, imap, izip
 
 __all__ = ["cmp","dircmp","cmpfiles"]
 
@@ -132,7 +132,7 @@ class dircmp:
     def phase1(self): # Compute common names
         a = dict(izip(imap(os.path.normcase, self.left_list), self.left_list))
         b = dict(izip(imap(os.path.normcase, self.right_list), self.right_list))
-        self.common = list(map(a.__getitem__, ifilter(b.__contains__, a)))
+        self.common = list(map(a.__getitem__, filter(b.__contains__, a)))
         self.left_only = list(map(a.__getitem__, ifilterfalse(b.__contains__, a)))
         self.right_only = list(map(b.__getitem__, ifilterfalse(a.__contains__, b)))
 
index 4e0902b7d2d09c21c3b340a734956575fbd5a628..13dc1f98f9734debc18c7c2e50cb37adfe1bbba5 100644 (file)
@@ -8,6 +8,7 @@ import random
 from functools import reduce
 maxsize = test_support.MAX_Py_ssize_t
 minsize = -maxsize-1
+ifilter = filter
 
 def lzip(*args):
     return list(zip(*args))
index c0de36dd899f51bfd2f28dc2996b1f76c5b6381b..1f2a43bc5dfd3ab4c1b2258857188df4e3bd5b5f 100644 (file)
@@ -2208,149 +2208,6 @@ static PyTypeObject combinations_type = {
 };
 
 
-/* ifilter object ************************************************************/
-
-typedef struct {
-       PyObject_HEAD
-       PyObject *func;
-       PyObject *it;
-} ifilterobject;
-
-static PyTypeObject ifilter_type;
-
-static PyObject *
-ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
-       PyObject *func, *seq;
-       PyObject *it;
-       ifilterobject *lz;
-
-       if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))
-               return NULL;
-
-       if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
-               return NULL;
-
-       /* Get iterator. */
-       it = PyObject_GetIter(seq);
-       if (it == NULL)
-               return NULL;
-
-       /* create ifilterobject structure */
-       lz = (ifilterobject *)type->tp_alloc(type, 0);
-       if (lz == NULL) {
-               Py_DECREF(it);
-               return NULL;
-       }
-       Py_INCREF(func);
-       lz->func = func;
-       lz->it = it;
-
-       return (PyObject *)lz;
-}
-
-static void
-ifilter_dealloc(ifilterobject *lz)
-{
-       PyObject_GC_UnTrack(lz);
-       Py_XDECREF(lz->func);
-       Py_XDECREF(lz->it);
-       Py_TYPE(lz)->tp_free(lz);
-}
-
-static int
-ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
-{
-       Py_VISIT(lz->it);
-       Py_VISIT(lz->func);
-       return 0;
-}
-
-static PyObject *
-ifilter_next(ifilterobject *lz)
-{
-       PyObject *item;
-       PyObject *it = lz->it;
-       long ok;
-       PyObject *(*iternext)(PyObject *);
-
-       assert(PyIter_Check(it));
-       iternext = *Py_TYPE(it)->tp_iternext;
-       for (;;) {
-               item = iternext(it);
-               if (item == NULL)
-                       return NULL;
-
-               if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {
-                       ok = PyObject_IsTrue(item);
-               } else {
-                       PyObject *good;
-                       good = PyObject_CallFunctionObjArgs(lz->func,
-                                                           item, NULL);
-                       if (good == NULL) {
-                               Py_DECREF(item);
-                               return NULL;
-                       }
-                       ok = PyObject_IsTrue(good);
-                       Py_DECREF(good);
-               }
-               if (ok)
-                       return item;
-               Py_DECREF(item);
-       }
-}
-
-PyDoc_STRVAR(ifilter_doc,
-"ifilter(function or None, sequence) --> ifilter object\n\
-\n\
-Return those items of sequence for which function(item) is true.\n\
-If function is None, return the items that are true.");
-
-static PyTypeObject ifilter_type = {
-       PyVarObject_HEAD_INIT(NULL, 0)
-       "itertools.ifilter",            /* tp_name */
-       sizeof(ifilterobject),          /* tp_basicsize */
-       0,                              /* tp_itemsize */
-       /* methods */
-       (destructor)ifilter_dealloc,    /* tp_dealloc */
-       0,                              /* tp_print */
-       0,                              /* tp_getattr */
-       0,                              /* tp_setattr */
-       0,                              /* tp_compare */
-       0,                              /* tp_repr */
-       0,                              /* tp_as_number */
-       0,                              /* tp_as_sequence */
-       0,                              /* tp_as_mapping */
-       0,                              /* tp_hash */
-       0,                              /* tp_call */
-       0,                              /* tp_str */
-       PyObject_GenericGetAttr,        /* tp_getattro */
-       0,                              /* tp_setattro */
-       0,                              /* tp_as_buffer */
-       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
-               Py_TPFLAGS_BASETYPE,    /* tp_flags */
-       ifilter_doc,                    /* tp_doc */
-       (traverseproc)ifilter_traverse, /* tp_traverse */
-       0,                              /* tp_clear */
-       0,                              /* tp_richcompare */
-       0,                              /* tp_weaklistoffset */
-       PyObject_SelfIter,              /* tp_iter */
-       (iternextfunc)ifilter_next,     /* tp_iternext */
-       0,                              /* tp_methods */
-       0,                              /* tp_members */
-       0,                              /* tp_getset */
-       0,                              /* tp_base */
-       0,                              /* tp_dict */
-       0,                              /* tp_descr_get */
-       0,                              /* tp_descr_set */
-       0,                              /* tp_dictoffset */
-       0,                              /* tp_init */
-       0,                              /* tp_alloc */
-       ifilter_new,                    /* tp_new */
-       PyObject_GC_Del,                /* tp_free */
-};
-
-
 /* ifilterfalse object ************************************************************/
 
 typedef struct {
@@ -3208,7 +3065,6 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
 Iterators terminating on the shortest input sequence:\n\
 izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
 izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
-ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
 ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
 islice(seq, [start,] stop [, step]) --> elements from\n\
        seq[start:stop:step]\n\
@@ -3242,7 +3098,6 @@ inititertools(void)
                &starmap_type,
                &imap_type,
                &chain_type,
-               &ifilter_type,
                &ifilterfalse_type,
                &count_type,
                &izip_type,
index 70237bf596ac1d5546553e011ec11f19301a1251..7baaf14213c8d1b653f909a32dda962d69f894e9 100644 (file)
@@ -277,29 +277,146 @@ PyDoc_STRVAR(bin_doc,
 Return the binary representation of an integer or long integer.");
 
 
+typedef struct {
+       PyObject_HEAD
+       PyObject *func;
+       PyObject *it;
+} filterobject;
+
+PyTypeObject PyFilter_Type;
+
 static PyObject *
-builtin_filter(PyObject *self, PyObject *args)
+filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-       PyObject *itertools, *ifilter, *result;
-       itertools = PyImport_ImportModuleNoBlock("itertools");
-       if (itertools == NULL)
+       PyObject *func, *seq;
+       PyObject *it;
+       filterobject *lz;
+
+       if (type == &PyFilter_Type && !_PyArg_NoKeywords("filter()", kwds))
                return NULL;
-       ifilter = PyObject_GetAttrString(itertools, "ifilter");
-       Py_DECREF(itertools);
-       if (ifilter == NULL)
+
+       if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq))
                return NULL;
-       result = PyObject_Call(ifilter, args, NULL);
-       Py_DECREF(ifilter);
-       return result;
+
+       /* Get iterator. */
+       it = PyObject_GetIter(seq);
+       if (it == NULL)
+               return NULL;
+
+       /* create filterobject structure */
+       lz = (filterobject *)type->tp_alloc(type, 0);
+       if (lz == NULL) {
+               Py_DECREF(it);
+               return NULL;
+       }
+       Py_INCREF(func);
+       lz->func = func;
+       lz->it = it;
+
+       return (PyObject *)lz;
+}
+
+static void
+filter_dealloc(filterobject *lz)
+{
+       PyObject_GC_UnTrack(lz);
+       Py_XDECREF(lz->func);
+       Py_XDECREF(lz->it);
+       Py_TYPE(lz)->tp_free(lz);
+}
+
+static int
+filter_traverse(filterobject *lz, visitproc visit, void *arg)
+{
+       Py_VISIT(lz->it);
+       Py_VISIT(lz->func);
+       return 0;
+}
+
+static PyObject *
+filter_next(filterobject *lz)
+{
+       PyObject *item;
+       PyObject *it = lz->it;
+       long ok;
+       PyObject *(*iternext)(PyObject *);
+
+       assert(PyIter_Check(it));
+       iternext = *Py_TYPE(it)->tp_iternext;
+       for (;;) {
+               item = iternext(it);
+               if (item == NULL)
+                       return NULL;
+
+               if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {
+                       ok = PyObject_IsTrue(item);
+               } else {
+                       PyObject *good;
+                       good = PyObject_CallFunctionObjArgs(lz->func,
+                                                           item, NULL);
+                       if (good == NULL) {
+                               Py_DECREF(item);
+                               return NULL;
+                       }
+                       ok = PyObject_IsTrue(good);
+                       Py_DECREF(good);
+               }
+               if (ok)
+                       return item;
+               Py_DECREF(item);
+       }
 }
 
 PyDoc_STRVAR(filter_doc,
-"filter(predicate, iterable) -> iterator\n\
+"filter(function or None, sequence) --> filter object\n\
 \n\
-Return an iterator yielding only those elements of the input iterable\n\
-for which the predicate (a Boolean function) returns true.\n\
-If the predicate is None, 'lambda x: bool(x)' is assumed.\n\
-(This is identical to itertools.ifilter().)");
+Return an iterator yielding those items of sequence for which function(item)\n\
+is true. If function is None, return the items that are true.");
+
+PyTypeObject PyFilter_Type = {
+       PyVarObject_HEAD_INIT(&PyType_Type, 0)
+       "filter",                       /* tp_name */
+       sizeof(filterobject),           /* tp_basicsize */
+       0,                              /* tp_itemsize */
+       /* methods */
+       (destructor)filter_dealloc,     /* tp_dealloc */
+       0,                              /* tp_print */
+       0,                              /* tp_getattr */
+       0,                              /* tp_setattr */
+       0,                              /* tp_compare */
+       0,                              /* tp_repr */
+       0,                              /* tp_as_number */
+       0,                              /* tp_as_sequence */
+       0,                              /* tp_as_mapping */
+       0,                              /* tp_hash */
+       0,                              /* tp_call */
+       0,                              /* tp_str */
+       PyObject_GenericGetAttr,        /* tp_getattro */
+       0,                              /* tp_setattro */
+       0,                              /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+               Py_TPFLAGS_BASETYPE,    /* tp_flags */
+       filter_doc,                     /* tp_doc */
+       (traverseproc)filter_traverse,  /* tp_traverse */
+       0,                              /* tp_clear */
+       0,                              /* tp_richcompare */
+       0,                              /* tp_weaklistoffset */
+       PyObject_SelfIter,              /* tp_iter */
+       (iternextfunc)filter_next,      /* tp_iternext */
+       0,                              /* tp_methods */
+       0,                              /* tp_members */
+       0,                              /* tp_getset */
+       0,                              /* tp_base */
+       0,                              /* tp_dict */
+       0,                              /* tp_descr_get */
+       0,                              /* tp_descr_set */
+       0,                              /* tp_dictoffset */
+       0,                              /* tp_init */
+       PyType_GenericAlloc,            /* tp_alloc */
+       filter_new,                     /* tp_new */
+       PyObject_GC_Del,                /* tp_free */
+};
+
 
 static PyObject *
 builtin_format(PyObject *self, PyObject *args)
@@ -1763,7 +1880,6 @@ static PyMethodDef builtin_methods[] = {
        {"divmod",      builtin_divmod,     METH_VARARGS, divmod_doc},
        {"eval",        builtin_eval,       METH_VARARGS, eval_doc},
        {"exec",        builtin_exec,       METH_VARARGS, exec_doc},
-       {"filter",      builtin_filter,     METH_VARARGS, filter_doc},
        {"format",      builtin_format,     METH_VARARGS, format_doc},
        {"getattr",     builtin_getattr,    METH_VARARGS, getattr_doc},
        {"globals",     (PyCFunction)builtin_globals,    METH_NOARGS, globals_doc},
@@ -1843,6 +1959,7 @@ _PyBuiltin_Init(void)
 #endif
        SETBUILTIN("dict",              &PyDict_Type);
        SETBUILTIN("enumerate",         &PyEnum_Type);
+       SETBUILTIN("filter",            &PyFilter_Type);
        SETBUILTIN("float",             &PyFloat_Type);
        SETBUILTIN("frozenset",         &PyFrozenSet_Type);
        SETBUILTIN("property",          &PyProperty_Type);