by constructs from the Haskell and SML programming languages. Each
has been recast in a form suitable for Python.
-With the advent of iterators and generators in Python 2.3, each of
-these tools can be expressed easily and succinctly in pure python.
-Rather duplicating what can already be done, this module emphasizes
-providing value in other ways:
-
-\begin{itemize}
-
- \item Instead of constructing an over-specialized toolset, this module
- provides basic building blocks that can be readily combined.
-
- For instance, SML provides a tabulation tool: \code{tabulate(\var{f})}
- which produces a sequence \code{f(0), f(1), ...}. This toolbox
- takes a different approach of providing \function{imap()} and
- \function{count()} which can be combined to form
- \code{imap(\var{f}, count())} and produce an equivalent result.
-
- \item Some tools were dropped because they offer no advantage over their
- pure python counterparts or because their behavior was too
- surprising.
-
- For instance, SML provides a tool: \code{cycle(\var{seq})} which
- loops over the sequence elements and then starts again when the
- sequence is exhausted. The surprising behavior is the need for
- significant auxiliary storage (unusual for iterators). Also, it
- is trivially implemented in python with almost no performance
- penalty.
-
- \item Another source of value comes from standardizing a core set of tools
- to avoid the readability and reliability problems that arise when many
- different individuals create their own slightly varying implementations
- each with their own quirks and naming conventions.
-
- \item Whether cast in pure python form or C code, tools that use iterators
- are more memory efficient (and faster) than their list based counterparts.
- Adopting the principles of just-in-time manufacturing, they create
- data when and where needed instead of consuming memory with the
- computer equivalent of ``inventory''.
-
-\end{itemize}
+The module standardizes a core set of fast, memory efficient tools
+that are useful by themselves or in combination. Standardization helps
+avoid the readability and reliability problems which arise when many
+different individuals create their own slightly varying implementations,
+each with their own quirks and naming conventions.
+
+The tools are designed to combine readily with each another. This makes
+it easy to construct more specialized tools succinctly and efficiently
+in pure Python.
+
+For instance, SML provides a tabulation tool: \code{tabulate(\var{f})}
+which produces a sequence \code{f(0), f(1), ...}. This toolbox
+provides \function{imap()} and \function{count()} which can be combined
+to form \code{imap(\var{f}, count())} and produce an equivalent result.
+
+Whether cast in pure python form or C code, tools that use iterators
+are more memory efficient (and faster) than their list based counterparts.
+Adopting the principles of just-in-time manufacturing, they create
+data when and where needed instead of consuming memory with the
+computer equivalent of ``inventory''.
+
+Some tools were omitted from the module because they offered no
+advantage over their pure python counterparts or because their behavior
+was too surprising.
+
+For instance, SML provides a tool: \code{cycle(\var{seq})} which
+loops over the sequence elements and then starts again when the
+sequence is exhausted. The surprising behavior is the need for
+significant auxiliary storage (which is unusual for an iterator).
+If needed, the tool is readily constructible using pure Python.
+
+Other tools are being considered for inclusion in future versions of the
+module. For instance, the function
+\function{chain(\var{it0}, \var{it1}, ...})} would return elements from
+the first iterator until it was exhausted and then move on to each
+successive iterator. The module author welcomes suggestions for other
+basic building blocks.
\begin{seealso}
\seetext{The Standard ML Basis Library,
\end{verbatim}
\end{funcdesc}
-\begin{funcdesc}{ifilter}{predicate, iterable \optional{, invert}}
+\begin{funcdesc}{ifilter}{predicate, iterable}
Make an iterator that filters elements from iterable returning only
- those for which the predicate is \code{True}. If
- \var{invert} is \code{True}, then reverse the process and pass through
- only those elements for which the predicate is \code{False}.
- If \var{predicate} is \code{None}, return the items that are true
- (or false if \var{invert} has been set). Equivalent to:
+ those for which the predicate is \code{True}.
+ If \var{predicate} is \code{None}, return the items that are true.
+ Equivalent to:
\begin{verbatim}
- def ifilter(predicate, iterable, invert=False):
- iterable = iter(iterable)
- while True:
- x = iterable.next()
- if predicate is None:
- b = bool(x)
- else:
- b = bool(predicate(x))
- if not invert and b or invert and not b:
+ def ifilter(predicate, iterable):
+ if predicate is None:
+ def predicate(x):
+ return x
+ for x in iterable:
+ if predicate(x):
+ yield x
+ \end{verbatim}
+\end{funcdesc}
+
+\begin{funcdesc}{ifilterfalse}{predicate, iterable}
+ Make an iterator that filters elements from iterable returning only
+ those for which the predicate is \code{False}.
+ If \var{predicate} is \code{None}, return the items that are false.
+ Equivalent to:
+
+ \begin{verbatim}
+ def ifilterfalse(predicate, iterable):
+ if predicate is None:
+ def predicate(x):
+ return x
+ for x in iterable:
+ if not predicate(x):
yield x
\end{verbatim}
\end{funcdesc}
\begin{verbatim}
def islice(iterable, *args):
- iterable = iter(iterable)
s = slice(*args)
next = s.start or 0
stop = s.stop
step = s.step or 1
- cnt = 0
- while True:
- while cnt < next:
- dummy = iterable.next()
- cnt += 1
- if cnt >= stop:
- break
- yield iterable.next()
- cnt += 1
- next += step
+ for cnt, element in enumerate(iterable):
+ if cnt < next:
+ continue
+ if cnt >= stop:
+ break
+ yield element
+ next += step
\end{verbatim}
\end{funcdesc}
>>> def nth(iterable, n):
... "Returns the nth item"
-... return islice(iterable, n, n+1).next()
+... return list(islice(iterable, n, n+1))
+
+>>> def all(pred, seq):
+... "Returns True if pred(x) is True for every element in the iterable"
+... return not nth(ifilterfalse(pred, seq), 0)
+
+>>> def some(pred, seq):
+... "Returns True if pred(x) is True at least one element in the iterable"
+... return bool(nth(ifilter(pred, seq), 0))
+
+>>> def no(pred, seq):
+... "Returns True if pred(x) is False for every element in the iterable"
+... return not nth(ifilter(pred, seq), 0)
\end{verbatim}
PyTypeObject dropwhile_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.dropwhile", /* tp_name */
- sizeof(dropwhileobject), /* tp_basicsize */
+ "itertools.dropwhile", /* tp_name */
+ sizeof(dropwhileobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)dropwhile_dealloc, /* tp_dealloc */
+ (destructor)dropwhile_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- dropwhile_doc, /* tp_doc */
+ dropwhile_doc, /* tp_doc */
(traverseproc)dropwhile_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)dropwhile_getiter, /* tp_iter */
- (iternextfunc)dropwhile_next, /* tp_iternext */
+ (getiterfunc)dropwhile_getiter, /* tp_iter */
+ (iternextfunc)dropwhile_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
- dropwhile_new, /* tp_new */
+ dropwhile_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
PyTypeObject takewhile_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.takewhile", /* tp_name */
- sizeof(takewhileobject), /* tp_basicsize */
+ "itertools.takewhile", /* tp_name */
+ sizeof(takewhileobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)takewhile_dealloc, /* tp_dealloc */
+ (destructor)takewhile_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- takewhile_doc, /* tp_doc */
+ takewhile_doc, /* tp_doc */
(traverseproc)takewhile_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)takewhile_getiter, /* tp_iter */
- (iternextfunc)takewhile_next, /* tp_iternext */
+ (getiterfunc)takewhile_getiter, /* tp_iter */
+ (iternextfunc)takewhile_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
- takewhile_new, /* tp_new */
+ takewhile_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
sizeof(isliceobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)islice_dealloc, /* tp_dealloc */
+ (destructor)islice_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- islice_doc, /* tp_doc */
- (traverseproc)islice_traverse, /* tp_traverse */
+ islice_doc, /* tp_doc */
+ (traverseproc)islice_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)islice_getiter, /* tp_iter */
- (iternextfunc)islice_next, /* tp_iternext */
+ (getiterfunc)islice_getiter, /* tp_iter */
+ (iternextfunc)islice_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
PyTypeObject starmap_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.starmap", /* tp_name */
- sizeof(starmapobject), /* tp_basicsize */
+ "itertools.starmap", /* tp_name */
+ sizeof(starmapobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)starmap_dealloc, /* tp_dealloc */
+ (destructor)starmap_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- starmap_doc, /* tp_doc */
- (traverseproc)starmap_traverse, /* tp_traverse */
+ starmap_doc, /* tp_doc */
+ (traverseproc)starmap_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)starmap_getiter, /* tp_iter */
- (iternextfunc)starmap_next, /* tp_iternext */
+ (getiterfunc)starmap_getiter, /* tp_iter */
+ (iternextfunc)starmap_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
- starmap_new, /* tp_new */
+ starmap_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
PyTypeObject imap_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.imap", /* tp_name */
- sizeof(imapobject), /* tp_basicsize */
+ "itertools.imap", /* tp_name */
+ sizeof(imapobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)imap_dealloc, /* tp_dealloc */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
- imap_new, /* tp_new */
+ imap_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
PyTypeObject times_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.times", /* tp_name */
- sizeof(timesobject), /* tp_basicsize */
+ "itertools.times", /* tp_name */
+ sizeof(timesobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)times_dealloc, /* tp_dealloc */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- times_doc, /* tp_doc */
+ times_doc, /* tp_doc */
(traverseproc)times_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)times_getiter, /* tp_iter */
- (iternextfunc)times_next, /* tp_iternext */
+ (getiterfunc)times_getiter, /* tp_iter */
+ (iternextfunc)times_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
PyObject_HEAD
PyObject *func;
PyObject *it;
- long invert;
} ifilterobject;
PyTypeObject ifilter_type;
static PyObject *
ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *func, *seq, *invert=NULL;
+ PyObject *func, *seq;
PyObject *it;
ifilterobject *lz;
- long inv=0;
- if (!PyArg_UnpackTuple(args, "ifilter", 2, 3, &func, &seq, &invert))
+ if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
return NULL;
- if (invert != NULL && PyObject_IsTrue(invert))
- inv = 1;
-
/* Get iterator. */
it = PyObject_GetIter(seq);
if (it == NULL)
Py_INCREF(func);
lz->func = func;
lz->it = it;
- lz->invert = inv;
return (PyObject *)lz;
}
ok = PyObject_IsTrue(good);
Py_DECREF(good);
}
- if (ok ^ lz->invert)
+ if (ok)
return item;
Py_DECREF(item);
}
}
PyDoc_STRVAR(ifilter_doc,
-"ifilter(function or None, sequence [, invert]) --> ifilter object\n\
+"ifilter(function or None, sequence) --> ifilter object\n\
\n\
-Return those items of sequence for which function(item) is true. If\n\
-invert is set to True, return items for which function(item) if False.\n\
-If function is None, return the items that are true (unless invert is set).");
+Return those items of sequence for which function(item) is true.\n\
+If function is None, return the items that are true.");
PyTypeObject ifilter_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.ifilter", /* tp_name */
- sizeof(ifilterobject), /* tp_basicsize */
+ "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 */
+ (getiterfunc)ifilter_getiter, /* 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 */
+ PyType_GenericAlloc, /* tp_alloc */
+ ifilter_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/* ifilterfalse object ************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+} ifilterfalseobject;
+
+PyTypeObject ifilterfalse_type;
+
+static PyObject *
+ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *func, *seq, *invert=NULL;
+ PyObject *it;
+ ifilterfalseobject *lz;
+
+ if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create ifilterfalseobject structure */
+ lz = (ifilterfalseobject *)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
+ifilterfalse_dealloc(ifilterfalseobject *lz)
+{
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+}
+
+static int
+ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
+{
+ int err;
+
+ if (lz->it) {
+ err = visit(lz->it, arg);
+ if (err)
+ return err;
+ }
+ if (lz->func) {
+ err = visit(lz->func, arg);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static PyObject *
+ifilterfalse_next(ifilterfalseobject *lz)
+{
+ PyObject *item;
+ long ok;
+
+ for (;;) {
+ item = PyIter_Next(lz->it);
+ if (item == NULL)
+ return NULL;
+
+ if (lz->func == Py_None) {
+ 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);
+ }
+}
+
+static PyObject *
+ifilterfalse_getiter(PyObject *lz)
+{
+ Py_INCREF(lz);
+ return lz;
+}
+
+PyDoc_STRVAR(ifilterfalse_doc,
+"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
+\n\
+Return those items of sequence for which function(item) is false.\n\
+If function is None, return the items that are false.");
+
+PyTypeObject ifilterfalse_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.ifilterfalse", /* tp_name */
+ sizeof(ifilterfalseobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)ifilter_dealloc, /* tp_dealloc */
+ (destructor)ifilterfalse_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
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 */
+ ifilterfalse_doc, /* tp_doc */
+ (traverseproc)ifilterfalse_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)ifilter_getiter, /* tp_iter */
- (iternextfunc)ifilter_next, /* tp_iternext */
+ (getiterfunc)ifilterfalse_getiter, /* tp_iter */
+ (iternextfunc)ifilterfalse_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
- ifilter_new, /* tp_new */
+ ifilterfalse_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
PyTypeObject count_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.count", /* tp_name */
- sizeof(countobject), /* tp_basicsize */
+ "itertools.count", /* tp_name */
+ sizeof(countobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)PyObject_Del, /* tp_dealloc */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
- count_doc, /* tp_doc */
+ count_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)count_getiter, /* tp_iter */
- (iternextfunc)count_next, /* tp_iternext */
+ (getiterfunc)count_getiter, /* tp_iter */
+ (iternextfunc)count_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
PyTypeObject izip_type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
- "itertools.izip", /* tp_name */
- sizeof(izipobject), /* tp_basicsize */
+ "itertools.izip", /* tp_name */
+ sizeof(izipobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)izip_dealloc, /* tp_dealloc */
+ (destructor)izip_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- izip_doc, /* tp_doc */
+ izip_doc, /* tp_doc */
(traverseproc)izip_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)izip_getiter, /* tp_iter */
- (iternextfunc)izip_next, /* tp_iternext */
+ (getiterfunc)izip_getiter, /* tp_iter */
+ (iternextfunc)izip_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
- izip_new, /* tp_new */
+ izip_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
sizeof(repeatobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)repeat_dealloc, /* tp_dealloc */
+ (destructor)repeat_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- repeat_doc, /* tp_doc */
- (traverseproc)repeat_traverse, /* tp_traverse */
+ repeat_doc, /* tp_doc */
+ (traverseproc)repeat_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
- (getiterfunc)repeat_getiter, /* tp_iter */
- (iternextfunc)repeat_next, /* tp_iternext */
+ (getiterfunc)repeat_getiter, /* tp_iter */
+ (iternextfunc)repeat_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
\n\
Iterators terminating on the shortest input sequence:\n\
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
-ifilter(pred, seq, invert=False) --> elements of seq where\n\
- pred(elem) is True (or False if invert is set)\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\
imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
PyMODINIT_FUNC
inititertools(void)
{
+ int i;
PyObject *m;
+ char *name;
+ PyTypeObject *typelist[] = {
+ &dropwhile_type,
+ &takewhile_type,
+ &islice_type,
+ &starmap_type,
+ &imap_type,
+ ×_type,
+ &ifilter_type,
+ &ifilterfalse_type,
+ &count_type,
+ &izip_type,
+ &repeat_type,
+ NULL
+ };
+
m = Py_InitModule3("itertools", NULL, module_doc);
- PyModule_AddObject(m, "dropwhile", (PyObject *)&dropwhile_type);
- if (PyType_Ready(&dropwhile_type) < 0)
- return;
- Py_INCREF(&dropwhile_type);
-
- PyModule_AddObject(m, "takewhile", (PyObject *)&takewhile_type);
- if (PyType_Ready(&takewhile_type) < 0)
- return;
- Py_INCREF(&takewhile_type);
-
- PyModule_AddObject(m, "islice", (PyObject *)&islice_type);
- if (PyType_Ready(&islice_type) < 0)
- return;
- Py_INCREF(&islice_type);
-
- PyModule_AddObject(m, "starmap", (PyObject *)&starmap_type);
- if (PyType_Ready(&starmap_type) < 0)
- return;
- Py_INCREF(&starmap_type);
-
- PyModule_AddObject(m, "imap", (PyObject *)&imap_type);
- if (PyType_Ready(&imap_type) < 0)
- return;
- Py_INCREF(&imap_type);
-
- PyModule_AddObject(m, "times", (PyObject *)×_type);
- if (PyType_Ready(×_type) < 0)
- return;
- Py_INCREF(×_type);
-
- if (PyType_Ready(&ifilter_type) < 0)
- return;
- Py_INCREF(&ifilter_type);
- PyModule_AddObject(m, "ifilter", (PyObject *)&ifilter_type);
-
- if (PyType_Ready(&count_type) < 0)
- return;
- Py_INCREF(&count_type);
- PyModule_AddObject(m, "count", (PyObject *)&count_type);
-
- if (PyType_Ready(&izip_type) < 0)
- return;
- Py_INCREF(&izip_type);
- PyModule_AddObject(m, "izip", (PyObject *)&izip_type);
-
- if (PyType_Ready(&repeat_type) < 0)
- return;
- Py_INCREF(&repeat_type);
- PyModule_AddObject(m, "repeat", (PyObject *)&repeat_type);
+ for (i=0 ; typelist[i] != NULL ; i++) {
+ if (PyType_Ready(typelist[i]) < 0)
+ return;
+ name = strchr(typelist[i]->tp_name, '.') + 1;
+ if (name == NULL)
+ return;
+ Py_INCREF(typelist[i]);
+ PyModule_AddObject(m, name, (PyObject *)typelist[i]);
+ }
}