[Python-checkins] python/nondist/sandbox/itertools itertools.c,1.3,1.4 libitertools.tex,1.4,1.5 test_itertools.py,1.2,1.3 todo.txt,1.4,1.5

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Sun, 26 Jan 2003 21:24:43 -0800


Update of /cvsroot/python/python/nondist/sandbox/itertools
In directory sc8-pr-cvs1:/tmp/cvs-serv25992

Modified Files:
	itertools.c libitertools.tex test_itertools.py todo.txt 
Log Message:
Added starmap().

Index: itertools.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** itertools.c	27 Jan 2003 04:24:14 -0000	1.3
--- itertools.c	27 Jan 2003 05:24:40 -0000	1.4
***************
*** 2,5 ****
--- 2,134 ----
  #include "Python.h"
  
+ 
+ /* starmap object ************************************************************/
+ 
+ typedef struct {
+         PyObject_HEAD
+         PyObject *func;
+         PyObject *it;
+ } starmapobject;
+ 
+ PyTypeObject starmap_type;
+ 
+ static PyObject *
+ starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+         PyObject *func, *seq;
+         PyObject *it;
+         starmapobject *lz;
+ 
+         if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
+                 return NULL;
+ 
+         /* Get iterator. */
+         it = PyObject_GetIter(seq);
+         if (it == NULL)
+                 return NULL;
+ 
+         /* create starmapobject structure */
+         lz = (starmapobject *)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
+ starmap_dealloc(starmapobject *lz)
+ {
+         PyObject_GC_UnTrack(lz);
+         Py_XDECREF(lz->func);
+         Py_XDECREF(lz->it);
+         lz->ob_type->tp_free(lz);
+ }
+ 
+ static int
+ starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
+ {
+         if (lz->it)
+                 return visit(lz->it, arg);
+         return 0;
+ }
+ 
+ static PyObject *
+ starmap_next(starmapobject *lz)
+ {
+         PyObject *args;
+ 	PyObject *result;
+   
+         args = PyIter_Next(lz->it);
+         if (args == NULL)
+                 return NULL;
+ 	result = PyObject_Call(lz->func, args, NULL);
+ 	Py_DECREF(args);
+ 	return result;
+ }
+ 
+ static PyObject *
+ starmap_getiter(PyObject *lz)
+ {
+         Py_INCREF(lz);
+         return lz;
+ }
+ 
+ PyDoc_STRVAR(starmap_doc,
+ "starmap(function, sequence) --> starmap object\n\
+ \n\
+ Return an iterator whose values are returned from the function evaluated\n\
+ with a argument tuple taken from the given sequence.");
+ 
+ PyTypeObject starmap_type = {
+         PyObject_HEAD_INIT(NULL)
+         0,                              /* ob_size */
+         "itertools.starmap",             /* tp_name */
+         sizeof(starmapobject),           /* tp_basicsize */
+         0,                              /* tp_itemsize */
+         /* methods */
+         (destructor)starmap_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 */
+         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 */
+         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 */
+         starmap_new,                     /* tp_new */
+         PyObject_GC_Del,                /* tp_free */
+ };
+ 
+ 
  /* imap object ************************************************************/
  
***************
*** 65,70 ****
  {
          PyObject_GC_UnTrack(lz);
!         //Py_XDECREF(lz->argtuple);
!         //Py_XDECREF(lz->iters);
          lz->ob_type->tp_free(lz);
  }
--- 194,199 ----
  {
          PyObject_GC_UnTrack(lz);
!         Py_XDECREF(lz->argtuple);
!         Py_XDECREF(lz->iters);
          lz->ob_type->tp_free(lz);
  }
***************
*** 289,292 ****
--- 418,422 ----
                  return NULL;
          }
+ 	Py_INCREF(func);
          lz->func = func;
          lz->it = it;
***************
*** 300,304 ****
  {
          PyObject_GC_UnTrack(lz);
!         //Py_XDECREF(lz->func);
          Py_XDECREF(lz->it);
          lz->ob_type->tp_free(lz);
--- 430,434 ----
  {
          PyObject_GC_UnTrack(lz);
!         Py_XDECREF(lz->func);
          Py_XDECREF(lz->it);
          lz->ob_type->tp_free(lz);
***************
*** 803,806 ****
--- 933,941 ----
          PyObject *m;
          m = Py_InitModule3("itertools", NULL, module_doc);
+ 
+         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);

Index: libitertools.tex
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** libitertools.tex	27 Jan 2003 04:24:14 -0000	1.4
--- libitertools.tex	27 Jan 2003 05:24:40 -0000	1.5
***************
*** 52,59 ****
          for \function{zip()} and run much faster.  It has nearly zero
          overhead since the looping is done in C code (bypassing Python's eval
! 	loop); since it returns an iterator (saving the need to allocate a
! 	list and append to it an element at a time); and since it reuses just
          one output list (saving the time to allocate and build a tuple on
! 	every pass).  Though very fast, using \function{loopzip()} outside of
          a \keyword{for} loop or other itertool can result in surprising
          behavior and an unwelcome refresher lesson in mutability.
--- 52,59 ----
          for \function{zip()} and run much faster.  It has nearly zero
          overhead since the looping is done in C code (bypassing Python's eval
!         loop); since it returns an iterator (saving the need to allocate a
!         list and append to it an element at a time); and since it reuses just
          one output list (saving the time to allocate and build a tuple on
!         every pass).  Though very fast, using \function{loopzip()} outside of
          a \keyword{for} loop or other itertool can result in surprising
          behavior and an unwelcome refresher lesson in mutability.
***************
*** 70,74 ****
          computer equivalent of ``inventory''.
  
! \end{itemize}    
  
  
--- 70,74 ----
          computer equivalent of ``inventory''.
  
! \end{itemize}
  
  
***************
*** 98,106 ****
    \begin{verbatim}
       def filter(func, iterable, invert=False):
! 	 iterable = iter(iterable)
           while True:
! 	     x = bool(iterable.next())
! 	     if not invert and x or invert and not x:
! 		 yield None
    \end{verbatim}
  \end{funcdesc}
--- 98,106 ----
    \begin{verbatim}
       def filter(func, iterable, invert=False):
!          iterable = iter(iterable)
           while True:
!              x = bool(iterable.next())
!              if not invert and x or invert and not x:
!                  yield None
    \end{verbatim}
  \end{funcdesc}
***************
*** 116,123 ****
    \begin{verbatim}
       def imap(func, *iterables):
! 	 iterables = map(iter, iterables)
           while True:
! 	     args = [i.next() for i in iterables]
! 	     yield f(*args)
    \end{verbatim}
  \end{funcdesc}
--- 116,123 ----
    \begin{verbatim}
       def imap(func, *iterables):
!          iterables = map(iter, iterables)
           while True:
!              args = [i.next() for i in iterables]
!              yield f(*args)
    \end{verbatim}
  \end{funcdesc}
***************
*** 135,144 ****
    \begin{verbatim}
       def loopzip(*iterables):
! 	 iterables = map(iter, iterables)
! 	 result = [None] * len(iterables)
           while True:
! 	     for i in xrange(len(iterables)):
! 		 result[i] = iterable[i].next()
! 	     yield result
    \end{verbatim}
  \end{funcdesc}
--- 135,144 ----
    \begin{verbatim}
       def loopzip(*iterables):
!          iterables = map(iter, iterables)
!          result = [None] * len(iterables)
           while True:
!              for i in xrange(len(iterables)):
!                  result[i] = iterable[i].next()
!              yield result
    \end{verbatim}
  \end{funcdesc}
***************
*** 156,159 ****
--- 156,171 ----
  \end{funcdesc}
  
+ \begin{funcdesc}{starmap}{func, iterable}
+   Make an iterator that computes the function using arguments tuples
+   obtained from the iterable.  Equivalent to:
+ 
+   \begin{verbatim}
+      def stapmap(func, iterable):
+          iterable = iter(iterable)
+          while True:
+              yield func(*iterable.next())
+   \end{verbatim}
+ \end{funcdesc}
+ 
  \begin{funcdesc}{times}{n}
    Make an iterator that returns None \var{n} times.
***************
*** 194,198 ****
  ...     print list(imap(operator.pow, bases, repeat(power)))
  ...
! \end{verbatim}                                                                                      
  
  As a further example of how itertools can be combined, here
--- 206,210 ----
  ...     print list(imap(operator.pow, bases, repeat(power)))
  ...
! \end{verbatim}
  
  As a further example of how itertools can be combined, here

Index: test_itertools.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** test_itertools.py	27 Jan 2003 04:24:14 -0000	1.2
--- test_itertools.py	27 Jan 2003 05:24:40 -0000	1.3
***************
*** 30,34 ****
          self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
                           [0**1, 1**2, 2**3])
!  
  def test_main():
      suite = unittest.TestSuite()
--- 30,40 ----
          self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
                           [0**1, 1**2, 2**3])
! 
!     def test_starmap(self):
!         import operator
!         self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
!                          [0**1, 1**2, 2**3])
! 
! 
  def test_main():
      suite = unittest.TestSuite()

Index: todo.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** todo.txt	27 Jan 2003 04:24:14 -0000	1.4
--- todo.txt	27 Jan 2003 05:24:40 -0000	1.5
***************
*** 2,6 ****
     islice(iterator, start, stop, step)
     iapply
-    starmap()
     takewhile(pred, seqn)
     dropwhile(pred, seqn)
--- 2,5 ----