Commit a88d4c7b authored by Raymond Hettinger's avatar Raymond Hettinger

Issue 2186 and 2187. Move filter from itertools to builtins.

parent 3c7018fd
...@@ -234,21 +234,6 @@ loops that truncate the stream. ...@@ -234,21 +234,6 @@ loops that truncate the stream.
self.currkey = self.keyfunc(self.currvalue) 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) .. function:: ifilterfalse(predicate, iterable)
Make an iterator that filters elements from iterable returning only those for Make an iterator that filters elements from iterable returning only those for
...@@ -606,13 +591,13 @@ which incur interpreter overhead. :: ...@@ -606,13 +591,13 @@ which incur interpreter overhead. ::
def any(seq, pred=None): def any(seq, pred=None):
"Returns True if pred(x) is true for at least one element in the iterable" "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 True
return False return False
def no(seq, pred=None): def no(seq, pred=None):
"Returns True if pred(x) is false for every element in the iterable" "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 False
return True return True
......
...@@ -12,7 +12,7 @@ Functions: ...@@ -12,7 +12,7 @@ Functions:
import os import os
import stat import stat
import warnings import warnings
from itertools import ifilter, ifilterfalse, imap, izip from itertools import ifilterfalse, imap, izip
__all__ = ["cmp","dircmp","cmpfiles"] __all__ = ["cmp","dircmp","cmpfiles"]
...@@ -132,7 +132,7 @@ class dircmp: ...@@ -132,7 +132,7 @@ class dircmp:
def phase1(self): # Compute common names def phase1(self): # Compute common names
a = dict(izip(imap(os.path.normcase, self.left_list), self.left_list)) 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)) 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.left_only = list(map(a.__getitem__, ifilterfalse(b.__contains__, a)))
self.right_only = list(map(b.__getitem__, ifilterfalse(a.__contains__, b))) self.right_only = list(map(b.__getitem__, ifilterfalse(a.__contains__, b)))
......
...@@ -8,6 +8,7 @@ import random ...@@ -8,6 +8,7 @@ import random
from functools import reduce from functools import reduce
maxsize = test_support.MAX_Py_ssize_t maxsize = test_support.MAX_Py_ssize_t
minsize = -maxsize-1 minsize = -maxsize-1
ifilter = filter
def lzip(*args): def lzip(*args):
return list(zip(*args)) return list(zip(*args))
......
...@@ -2208,149 +2208,6 @@ static PyTypeObject combinations_type = { ...@@ -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 ************************************************************/ /* ifilterfalse object ************************************************************/
typedef struct { typedef struct {
...@@ -3208,7 +3065,6 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ ...@@ -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\ Iterators terminating on the shortest input sequence:\n\
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \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\ 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\ ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
islice(seq, [start,] stop [, step]) --> elements from\n\ islice(seq, [start,] stop [, step]) --> elements from\n\
seq[start:stop:step]\n\ seq[start:stop:step]\n\
...@@ -3242,7 +3098,6 @@ inititertools(void) ...@@ -3242,7 +3098,6 @@ inititertools(void)
&starmap_type, &starmap_type,
&imap_type, &imap_type,
&chain_type, &chain_type,
&ifilter_type,
&ifilterfalse_type, &ifilterfalse_type,
&count_type, &count_type,
&izip_type, &izip_type,
......
...@@ -277,29 +277,146 @@ PyDoc_STRVAR(bin_doc, ...@@ -277,29 +277,146 @@ PyDoc_STRVAR(bin_doc,
Return the binary representation of an integer or long integer."); Return the binary representation of an integer or long integer.");
typedef struct {
PyObject_HEAD
PyObject *func;
PyObject *it;
} filterobject;
PyTypeObject PyFilter_Type;
static PyObject * static PyObject *
builtin_filter(PyObject *self, PyObject *args) filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
PyObject *itertools, *ifilter, *result; PyObject *func, *seq;
itertools = PyImport_ImportModuleNoBlock("itertools"); PyObject *it;
if (itertools == NULL) filterobject *lz;
if (type == &PyFilter_Type && !_PyArg_NoKeywords("filter()", kwds))
return NULL; return NULL;
ifilter = PyObject_GetAttrString(itertools, "ifilter");
Py_DECREF(itertools); if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq))
if (ifilter == NULL)
return NULL; return NULL;
result = PyObject_Call(ifilter, args, NULL);
Py_DECREF(ifilter); /* Get iterator. */
return result; 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, PyDoc_STRVAR(filter_doc,
"filter(predicate, iterable) -> iterator\n\ "filter(function or None, sequence) --> filter object\n\
\n\ \n\
Return an iterator yielding only those elements of the input iterable\n\ Return an iterator yielding those items of sequence for which function(item)\n\
for which the predicate (a Boolean function) returns true.\n\ is true. If function is None, return the items that are true.");
If the predicate is None, 'lambda x: bool(x)' is assumed.\n\
(This is identical to itertools.ifilter().)"); 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 * static PyObject *
builtin_format(PyObject *self, PyObject *args) builtin_format(PyObject *self, PyObject *args)
...@@ -1763,7 +1880,6 @@ static PyMethodDef builtin_methods[] = { ...@@ -1763,7 +1880,6 @@ static PyMethodDef builtin_methods[] = {
{"divmod", builtin_divmod, METH_VARARGS, divmod_doc}, {"divmod", builtin_divmod, METH_VARARGS, divmod_doc},
{"eval", builtin_eval, METH_VARARGS, eval_doc}, {"eval", builtin_eval, METH_VARARGS, eval_doc},
{"exec", builtin_exec, METH_VARARGS, exec_doc}, {"exec", builtin_exec, METH_VARARGS, exec_doc},
{"filter", builtin_filter, METH_VARARGS, filter_doc},
{"format", builtin_format, METH_VARARGS, format_doc}, {"format", builtin_format, METH_VARARGS, format_doc},
{"getattr", builtin_getattr, METH_VARARGS, getattr_doc}, {"getattr", builtin_getattr, METH_VARARGS, getattr_doc},
{"globals", (PyCFunction)builtin_globals, METH_NOARGS, globals_doc}, {"globals", (PyCFunction)builtin_globals, METH_NOARGS, globals_doc},
...@@ -1843,6 +1959,7 @@ _PyBuiltin_Init(void) ...@@ -1843,6 +1959,7 @@ _PyBuiltin_Init(void)
#endif #endif
SETBUILTIN("dict", &PyDict_Type); SETBUILTIN("dict", &PyDict_Type);
SETBUILTIN("enumerate", &PyEnum_Type); SETBUILTIN("enumerate", &PyEnum_Type);
SETBUILTIN("filter", &PyFilter_Type);
SETBUILTIN("float", &PyFloat_Type); SETBUILTIN("float", &PyFloat_Type);
SETBUILTIN("frozenset", &PyFrozenSet_Type); SETBUILTIN("frozenset", &PyFrozenSet_Type);
SETBUILTIN("property", &PyProperty_Type); SETBUILTIN("property", &PyProperty_Type);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment