[Python-checkins] python/nondist/sandbox/itertools NEWS,NONE,1.1 itertools.c,1.7,1.8 libitertools.tex,1.7,1.8 test_itertools.py,1.5,1.6 todo.txt,1.8,1.9
rhettinger@users.sourceforge.net
rhettinger@users.sourceforge.net
Mon, 27 Jan 2003 04:16:45 -0800
Update of /cvsroot/python/python/nondist/sandbox/itertools
In directory sc8-pr-cvs1:/tmp/cvs-serv26261
Modified Files:
itertools.c libitertools.tex test_itertools.py todo.txt
Added Files:
NEWS
Log Message:
Add dropwhile().
--- NEW FILE: NEWS ---
- Added an itertools module containing high speed looping constructs
inspired by tools in Haskell and SML.
Index: itertools.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** itertools.c 27 Jan 2003 11:17:45 -0000 1.7
--- itertools.c 27 Jan 2003 12:16:42 -0000 1.8
***************
*** 2,5 ****
--- 2,150 ----
#include "Python.h"
+ /* dropwhile object ************************************************************/
+
+ typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+ PyObject *it;
+ long start;
+ } dropwhileobject;
+
+ PyTypeObject dropwhile_type;
+
+ static PyObject *
+ dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ PyObject *func, *seq;
+ PyObject *it;
+ dropwhileobject *lz;
+
+ if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
+ return NULL;
+
+ /* Get iterator. */
+ it = PyObject_GetIter(seq);
+ if (it == NULL)
+ return NULL;
+
+ /* create dropwhileobject structure */
+ lz = (dropwhileobject *)type->tp_alloc(type, 0);
+ if (lz == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_INCREF(func);
+ lz->func = func;
+ lz->it = it;
+ lz->start = 0;
+
+ return (PyObject *)lz;
+ }
+
+ static void
+ dropwhile_dealloc(dropwhileobject *lz)
+ {
+ PyObject_GC_UnTrack(lz);
+ Py_XDECREF(lz->func);
+ Py_XDECREF(lz->it);
+ lz->ob_type->tp_free(lz);
+ }
+
+ static int
+ dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
+ {
+ if (lz->it)
+ return visit(lz->it, arg);
+ return 0;
+ }
+
+ static PyObject *
+ dropwhile_next(dropwhileobject *lz)
+ {
+ PyObject *item, *good;
+ long ok;
+
+ for (;;) {
+ item = PyIter_Next(lz->it);
+ if (item == NULL)
+ return NULL;
+ if (lz->start == 1)
+ return item;
+
+ good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
+ if (good == NULL) {
+ printf("R");
+ Py_DECREF(item);
+ return NULL;
+ }
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
+ if (!ok) {
+ lz->start = 1;
+ return item;
+ }
+ Py_DECREF(item);
+ }
+ }
+
+ static PyObject *
+ dropwhile_getiter(PyObject *lz)
+ {
+ Py_INCREF(lz);
+ return lz;
+ }
+
+ PyDoc_STRVAR(dropwhile_doc,
+ "dropwhile(predicate, iterable) --> dropwhile object\n\
+ \n\
+ Drop items from the iterable while predicate(item) is true.\n\
+ Afterwards, return every element until the iterable is exhausted.");
+
+ PyTypeObject dropwhile_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "itertools.dropwhile", /* tp_name */
+ sizeof(dropwhileobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dropwhile_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 */
+ 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 */
+ 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 */
+ dropwhile_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+ };
+
+
/* takewhile object ************************************************************/
***************
*** 1233,1243 ****
same list each time but with updated contents\n\
ifilter(pred, seq, invert=False) --> elements of seq where\n\
! pred(elem) is True (or False invert is set)\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\
starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\
times(n) --> None, None, ... for n times.\n\
takewhile(pred, seq) --> s[0], s[1], until pred fails\n\
");
--- 1378,1389 ----
same list each time but with updated contents\n\
ifilter(pred, seq, invert=False) --> elements of seq where\n\
! pred(elem) is True (or False if invert is set)\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\
starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\
times(n) --> None, None, ... for n times.\n\
takewhile(pred, seq) --> s[0], s[1], until pred fails\n\
+ dropwhile(pred, seq) --> s[n], s[n+1], starting when pred fails\n\
");
***************
*** 1248,1251 ****
--- 1394,1402 ----
PyObject *m;
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);
Index: libitertools.tex
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** libitertools.tex 27 Jan 2003 10:44:52 -0000 1.7
--- libitertools.tex 27 Jan 2003 12:16:42 -0000 1.8
***************
*** 74,83 ****
\begin{seealso}
\seetext{The Standard ML Basis Library,
! \citetitle[http://www.standardml.org/Basis/]
! {The Standard ML Basis Library}.}
\seetext{Haskell, A Purely Functional Language,
\citetitle[http://www.haskell.org/definition/]
! {Definition of Haskell and the Standard Libraries}.}
\end{seealso}
--- 74,83 ----
\begin{seealso}
\seetext{The Standard ML Basis Library,
! \citetitle[http://www.standardml.org/Basis/]
! {The Standard ML Basis Library}.}
\seetext{Haskell, A Purely Functional Language,
\citetitle[http://www.haskell.org/definition/]
! {Definition of Haskell and the Standard Libraries}.}
\end{seealso}
***************
*** 102,105 ****
--- 102,123 ----
\end{funcdesc}
+ \begin{funcdesc}{dropwhile}{predicate, iterable}
+ Make an iterator that drops elements from the iterable as long as
+ the predicate is true; afterwards, returns every element.
+ Equivalent to:
+
+ \begin{verbatim}
+ def dropwhile(func, iterable, invert=False):
+ iterable = iter(iterable)
+ while True:
+ x = iterable.next()
+ if not predicate(x):
+ yield x
+ break
+ while True:
+ yield iterable.next()
+ \end{verbatim}
+ \end{funcdesc}
+
\begin{funcdesc}{ifilter}{func, iterable \optional{, invert}}
Make an iterator that filters elements from iterable returning only
***************
*** 200,203 ****
--- 218,237 ----
while True:
yield func(*iterable.next())
+ \end{verbatim}
+ \end{funcdesc}
+
+ \begin{funcdesc}{takewhile}{predicate, iterable}
+ Make an iterator that returns elements from the iterable as long as
+ the predicate is true. Equivalent to:
+
+ \begin{verbatim}
+ def takewhile(func, iterable, invert=False):
+ iterable = iter(iterable)
+ while True:
+ x = iterable.next()
+ if predicate(x):
+ yield x
+ else:
+ break
\end{verbatim}
\end{funcdesc}
Index: test_itertools.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** test_itertools.py 27 Jan 2003 11:17:45 -0000 1.5
--- test_itertools.py 27 Jan 2003 12:16:42 -0000 1.6
***************
*** 75,82 ****
self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
! ## def test_dropwhile(self):
! ## data = [1, 3, 5, 20, 2, 4, 6, 8]
! ## underten = lambda x: x<10
! ## self.assertEqual(list(takewhile(underten, data)), [20, 2, 4, 6, 8])
def test_main():
--- 75,82 ----
self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
! def test_dropwhile(self):
! data = [1, 3, 5, 20, 2, 4, 6, 8]
! underten = lambda x: x<10
! self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
def test_main():
Index: todo.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** todo.txt 27 Jan 2003 11:17:45 -0000 1.8
--- todo.txt 27 Jan 2003 12:16:42 -0000 1.9
***************
*** 1,5 ****
Add:
iapply(func) ?? what did this do in SML
- dropwhile(pred, seqn)
unzip(seqn) ?? does this make sense for iterators
exists() and any() ?? these don't return iterators
--- 1,4 ----
***************
*** 16,19 ****
Things that just bug me:
! islice is supposed to looklike i-slice but can be read as is-lice
--- 15,18 ----
Things that just bug me:
! islice is supposed to sound like i-slice but can be read as is-lice