4 /* Itertools module written and maintained
5 by Raymond D. Hettinger <python@rcn.com>
6 Copyright (c) 2003 Python Software Foundation.
10 /* cycle object **********************************************************/
19 static PyTypeObject cycle_type
;
22 cycle_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
29 if (!PyArg_UnpackTuple(args
, "cycle", 1, 1, &iterable
))
33 it
= PyObject_GetIter(iterable
);
37 saved
= PyList_New(0);
43 /* create cycleobject structure */
44 lz
= (cycleobject
*)type
->tp_alloc(type
, 0);
54 return (PyObject
*)lz
;
58 cycle_dealloc(cycleobject
*lz
)
60 PyObject_GC_UnTrack(lz
);
61 Py_XDECREF(lz
->saved
);
63 lz
->ob_type
->tp_free(lz
);
67 cycle_traverse(cycleobject
*lz
, visitproc visit
, void *arg
)
72 err
= visit(lz
->it
, arg
);
77 err
= visit(lz
->saved
, arg
);
85 cycle_next(cycleobject
*lz
)
91 item
= PyIter_Next(lz
->it
);
94 PyList_Append(lz
->saved
, item
);
97 if (PyErr_Occurred()) {
98 if (PyErr_ExceptionMatches(PyExc_StopIteration
))
103 if (PyList_Size(lz
->saved
) == 0)
105 it
= PyObject_GetIter(lz
->saved
);
114 PyDoc_STRVAR(cycle_doc
,
115 "cycle(iterable) --> cycle object\n\
117 Return elements from the iterable until it is exhausted.\n\
118 Then repeat the sequence indefinitely.");
120 static PyTypeObject cycle_type
= {
121 PyObject_HEAD_INIT(NULL
)
123 "itertools.cycle", /* tp_name */
124 sizeof(cycleobject
), /* tp_basicsize */
127 (destructor
)cycle_dealloc
, /* tp_dealloc */
133 0, /* tp_as_number */
134 0, /* tp_as_sequence */
135 0, /* tp_as_mapping */
139 PyObject_GenericGetAttr
, /* tp_getattro */
141 0, /* tp_as_buffer */
142 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
143 Py_TPFLAGS_BASETYPE
, /* tp_flags */
144 cycle_doc
, /* tp_doc */
145 (traverseproc
)cycle_traverse
, /* tp_traverse */
147 0, /* tp_richcompare */
148 0, /* tp_weaklistoffset */
149 PyObject_SelfIter
, /* tp_iter */
150 (iternextfunc
)cycle_next
, /* tp_iternext */
156 0, /* tp_descr_get */
157 0, /* tp_descr_set */
158 0, /* tp_dictoffset */
161 cycle_new
, /* tp_new */
162 PyObject_GC_Del
, /* tp_free */
166 /* dropwhile object **********************************************************/
175 static PyTypeObject dropwhile_type
;
178 dropwhile_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
180 PyObject
*func
, *seq
;
184 if (!PyArg_UnpackTuple(args
, "dropwhile", 2, 2, &func
, &seq
))
188 it
= PyObject_GetIter(seq
);
192 /* create dropwhileobject structure */
193 lz
= (dropwhileobject
*)type
->tp_alloc(type
, 0);
203 return (PyObject
*)lz
;
207 dropwhile_dealloc(dropwhileobject
*lz
)
209 PyObject_GC_UnTrack(lz
);
210 Py_XDECREF(lz
->func
);
212 lz
->ob_type
->tp_free(lz
);
216 dropwhile_traverse(dropwhileobject
*lz
, visitproc visit
, void *arg
)
221 err
= visit(lz
->it
, arg
);
226 err
= visit(lz
->func
, arg
);
234 dropwhile_next(dropwhileobject
*lz
)
236 PyObject
*item
, *good
;
237 PyObject
*it
= lz
->it
;
241 assert(PyIter_Check(it
));
242 item
= (*it
->ob_type
->tp_iternext
)(it
);
248 good
= PyObject_CallFunctionObjArgs(lz
->func
, item
, NULL
);
253 ok
= PyObject_IsTrue(good
);
263 PyDoc_STRVAR(dropwhile_doc
,
264 "dropwhile(predicate, iterable) --> dropwhile object\n\
266 Drop items from the iterable while predicate(item) is true.\n\
267 Afterwards, return every element until the iterable is exhausted.");
269 static PyTypeObject dropwhile_type
= {
270 PyObject_HEAD_INIT(NULL
)
272 "itertools.dropwhile", /* tp_name */
273 sizeof(dropwhileobject
), /* tp_basicsize */
276 (destructor
)dropwhile_dealloc
, /* tp_dealloc */
282 0, /* tp_as_number */
283 0, /* tp_as_sequence */
284 0, /* tp_as_mapping */
288 PyObject_GenericGetAttr
, /* tp_getattro */
290 0, /* tp_as_buffer */
291 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
292 Py_TPFLAGS_BASETYPE
, /* tp_flags */
293 dropwhile_doc
, /* tp_doc */
294 (traverseproc
)dropwhile_traverse
, /* tp_traverse */
296 0, /* tp_richcompare */
297 0, /* tp_weaklistoffset */
298 PyObject_SelfIter
, /* tp_iter */
299 (iternextfunc
)dropwhile_next
, /* tp_iternext */
305 0, /* tp_descr_get */
306 0, /* tp_descr_set */
307 0, /* tp_dictoffset */
310 dropwhile_new
, /* tp_new */
311 PyObject_GC_Del
, /* tp_free */
315 /* takewhile object **********************************************************/
324 static PyTypeObject takewhile_type
;
327 takewhile_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
329 PyObject
*func
, *seq
;
333 if (!PyArg_UnpackTuple(args
, "takewhile", 2, 2, &func
, &seq
))
337 it
= PyObject_GetIter(seq
);
341 /* create takewhileobject structure */
342 lz
= (takewhileobject
*)type
->tp_alloc(type
, 0);
352 return (PyObject
*)lz
;
356 takewhile_dealloc(takewhileobject
*lz
)
358 PyObject_GC_UnTrack(lz
);
359 Py_XDECREF(lz
->func
);
361 lz
->ob_type
->tp_free(lz
);
365 takewhile_traverse(takewhileobject
*lz
, visitproc visit
, void *arg
)
370 err
= visit(lz
->it
, arg
);
375 err
= visit(lz
->func
, arg
);
383 takewhile_next(takewhileobject
*lz
)
385 PyObject
*item
, *good
;
386 PyObject
*it
= lz
->it
;
392 assert(PyIter_Check(it
));
393 item
= (*it
->ob_type
->tp_iternext
)(it
);
397 good
= PyObject_CallFunctionObjArgs(lz
->func
, item
, NULL
);
402 ok
= PyObject_IsTrue(good
);
411 PyDoc_STRVAR(takewhile_doc
,
412 "takewhile(predicate, iterable) --> takewhile object\n\
414 Return successive entries from an iterable as long as the \n\
415 predicate evaluates to true for each entry.");
417 static PyTypeObject takewhile_type
= {
418 PyObject_HEAD_INIT(NULL
)
420 "itertools.takewhile", /* tp_name */
421 sizeof(takewhileobject
), /* tp_basicsize */
424 (destructor
)takewhile_dealloc
, /* tp_dealloc */
430 0, /* tp_as_number */
431 0, /* tp_as_sequence */
432 0, /* tp_as_mapping */
436 PyObject_GenericGetAttr
, /* tp_getattro */
438 0, /* tp_as_buffer */
439 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
440 Py_TPFLAGS_BASETYPE
, /* tp_flags */
441 takewhile_doc
, /* tp_doc */
442 (traverseproc
)takewhile_traverse
, /* tp_traverse */
444 0, /* tp_richcompare */
445 0, /* tp_weaklistoffset */
446 PyObject_SelfIter
, /* tp_iter */
447 (iternextfunc
)takewhile_next
, /* tp_iternext */
453 0, /* tp_descr_get */
454 0, /* tp_descr_set */
455 0, /* tp_dictoffset */
458 takewhile_new
, /* tp_new */
459 PyObject_GC_Del
, /* tp_free */
463 /* islice object ************************************************************/
474 static PyTypeObject islice_type
;
477 islice_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
480 long start
=0, stop
=-1, step
=1;
481 PyObject
*it
, *a1
=NULL
, *a2
=NULL
;
485 numargs
= PyTuple_Size(args
);
486 if (!PyArg_ParseTuple(args
, "OO|Ol:islice", &seq
, &a1
, &a2
, &step
))
491 stop
= PyInt_AsLong(a1
);
493 if (PyErr_Occurred())
495 PyErr_SetString(PyExc_ValueError
,
496 "Stop argument must be an integer or None.");
501 start
= PyInt_AsLong(a1
);
502 if (start
== -1 && PyErr_Occurred()) {
504 PyErr_SetString(PyExc_ValueError
,
505 "Start argument must be an integer.");
509 stop
= PyInt_AsLong(a2
);
511 if (PyErr_Occurred())
513 PyErr_SetString(PyExc_ValueError
,
514 "Stop argument must be an integer or None.");
520 if (start
<0 || stop
<-1) {
521 PyErr_SetString(PyExc_ValueError
,
522 "Indices for islice() must be positive.");
527 PyErr_SetString(PyExc_ValueError
,
528 "Step must be one or larger for islice().");
533 it
= PyObject_GetIter(seq
);
537 /* create isliceobject structure */
538 lz
= (isliceobject
*)type
->tp_alloc(type
, 0);
549 return (PyObject
*)lz
;
553 islice_dealloc(isliceobject
*lz
)
555 PyObject_GC_UnTrack(lz
);
557 lz
->ob_type
->tp_free(lz
);
561 islice_traverse(isliceobject
*lz
, visitproc visit
, void *arg
)
564 return visit(lz
->it
, arg
);
569 islice_next(isliceobject
*lz
)
572 PyObject
*it
= lz
->it
;
575 while (lz
->cnt
< lz
->next
) {
576 assert(PyIter_Check(it
));
577 item
= (*it
->ob_type
->tp_iternext
)(it
);
583 if (lz
->stop
!= -1 && lz
->cnt
>= lz
->stop
)
585 assert(PyIter_Check(it
));
586 item
= (*it
->ob_type
->tp_iternext
)(it
);
591 lz
->next
+= lz
->step
;
592 if (lz
->next
< oldnext
) /* Check for overflow */
597 PyDoc_STRVAR(islice_doc
,
598 "islice(iterable, [start,] stop [, step]) --> islice object\n\
600 Return an iterator whose next() method returns selected values from an\n\
601 iterable. If start is specified, will skip all preceding elements;\n\
602 otherwise, start defaults to zero. Step defaults to one. If\n\
603 specified as another value, step determines how many values are \n\
604 skipped between successive calls. Works like a slice() on a list\n\
605 but returns an iterator.");
607 static PyTypeObject islice_type
= {
608 PyObject_HEAD_INIT(NULL
)
610 "itertools.islice", /* tp_name */
611 sizeof(isliceobject
), /* tp_basicsize */
614 (destructor
)islice_dealloc
, /* tp_dealloc */
620 0, /* tp_as_number */
621 0, /* tp_as_sequence */
622 0, /* tp_as_mapping */
626 PyObject_GenericGetAttr
, /* tp_getattro */
628 0, /* tp_as_buffer */
629 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
630 Py_TPFLAGS_BASETYPE
, /* tp_flags */
631 islice_doc
, /* tp_doc */
632 (traverseproc
)islice_traverse
, /* tp_traverse */
634 0, /* tp_richcompare */
635 0, /* tp_weaklistoffset */
636 PyObject_SelfIter
, /* tp_iter */
637 (iternextfunc
)islice_next
, /* tp_iternext */
643 0, /* tp_descr_get */
644 0, /* tp_descr_set */
645 0, /* tp_dictoffset */
648 islice_new
, /* tp_new */
649 PyObject_GC_Del
, /* tp_free */
653 /* starmap object ************************************************************/
661 static PyTypeObject starmap_type
;
664 starmap_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
666 PyObject
*func
, *seq
;
670 if (!PyArg_UnpackTuple(args
, "starmap", 2, 2, &func
, &seq
))
674 it
= PyObject_GetIter(seq
);
678 /* create starmapobject structure */
679 lz
= (starmapobject
*)type
->tp_alloc(type
, 0);
688 return (PyObject
*)lz
;
692 starmap_dealloc(starmapobject
*lz
)
694 PyObject_GC_UnTrack(lz
);
695 Py_XDECREF(lz
->func
);
697 lz
->ob_type
->tp_free(lz
);
701 starmap_traverse(starmapobject
*lz
, visitproc visit
, void *arg
)
706 err
= visit(lz
->it
, arg
);
711 err
= visit(lz
->func
, arg
);
719 starmap_next(starmapobject
*lz
)
723 PyObject
*it
= lz
->it
;
725 assert(PyIter_Check(it
));
726 args
= (*it
->ob_type
->tp_iternext
)(it
);
729 if (!PyTuple_CheckExact(args
)) {
731 PyErr_SetString(PyExc_TypeError
,
732 "iterator must return a tuple");
735 result
= PyObject_Call(lz
->func
, args
, NULL
);
740 PyDoc_STRVAR(starmap_doc
,
741 "starmap(function, sequence) --> starmap object\n\
743 Return an iterator whose values are returned from the function evaluated\n\
744 with a argument tuple taken from the given sequence.");
746 static PyTypeObject starmap_type
= {
747 PyObject_HEAD_INIT(NULL
)
749 "itertools.starmap", /* tp_name */
750 sizeof(starmapobject
), /* tp_basicsize */
753 (destructor
)starmap_dealloc
, /* tp_dealloc */
759 0, /* tp_as_number */
760 0, /* tp_as_sequence */
761 0, /* tp_as_mapping */
765 PyObject_GenericGetAttr
, /* tp_getattro */
767 0, /* tp_as_buffer */
768 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
769 Py_TPFLAGS_BASETYPE
, /* tp_flags */
770 starmap_doc
, /* tp_doc */
771 (traverseproc
)starmap_traverse
, /* tp_traverse */
773 0, /* tp_richcompare */
774 0, /* tp_weaklistoffset */
775 PyObject_SelfIter
, /* tp_iter */
776 (iternextfunc
)starmap_next
, /* tp_iternext */
782 0, /* tp_descr_get */
783 0, /* tp_descr_set */
784 0, /* tp_dictoffset */
787 starmap_new
, /* tp_new */
788 PyObject_GC_Del
, /* tp_free */
792 /* imap object ************************************************************/
800 static PyTypeObject imap_type
;
803 imap_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
805 PyObject
*it
, *iters
, *func
;
809 numargs
= PyTuple_Size(args
);
811 PyErr_SetString(PyExc_TypeError
,
812 "imap() must have at least two arguments.");
816 iters
= PyTuple_New(numargs
-1);
820 for (i
=1 ; i
<numargs
; i
++) {
822 it
= PyObject_GetIter(PyTuple_GET_ITEM(args
, i
));
827 PyTuple_SET_ITEM(iters
, i
-1, it
);
830 /* create imapobject structure */
831 lz
= (imapobject
*)type
->tp_alloc(type
, 0);
837 func
= PyTuple_GET_ITEM(args
, 0);
841 return (PyObject
*)lz
;
845 imap_dealloc(imapobject
*lz
)
847 PyObject_GC_UnTrack(lz
);
848 Py_XDECREF(lz
->iters
);
849 Py_XDECREF(lz
->func
);
850 lz
->ob_type
->tp_free(lz
);
854 imap_traverse(imapobject
*lz
, visitproc visit
, void *arg
)
859 err
= visit(lz
->iters
, arg
);
864 err
= visit(lz
->func
, arg
);
872 imap() is an iterator version of __builtins__.map() except that it does
873 not have the None fill-in feature. That was intentionally left out for
874 the following reasons:
876 1) Itertools are designed to be easily combined and chained together.
877 Having all tools stop with the shortest input is a unifying principle
878 that makes it easier to combine finite iterators (supplying data) with
879 infinite iterators like count() and repeat() (for supplying sequential
880 or constant arguments to a function).
882 2) In typical use cases for combining itertools, having one finite data
883 supplier run out before another is likely to be an error condition which
884 should not pass silently by automatically supplying None.
886 3) The use cases for automatic None fill-in are rare -- not many functions
887 do something useful when a parameter suddenly switches type and becomes
890 4) If a need does arise, it can be met by __builtins__.map() or by
891 writing: chain(iterable, repeat(None)).
893 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
897 imap_next(imapobject
*lz
)
904 numargs
= PyTuple_Size(lz
->iters
);
905 argtuple
= PyTuple_New(numargs
);
906 if (argtuple
== NULL
)
909 for (i
=0 ; i
<numargs
; i
++) {
910 val
= PyIter_Next(PyTuple_GET_ITEM(lz
->iters
, i
));
915 PyTuple_SET_ITEM(argtuple
, i
, val
);
917 if (lz
->func
== Py_None
)
919 result
= PyObject_Call(lz
->func
, argtuple
, NULL
);
924 PyDoc_STRVAR(imap_doc
,
925 "imap(func, *iterables) --> imap object\n\
927 Make an iterator that computes the function using arguments from\n\
928 each of the iterables. Like map() except that it returns\n\
929 an iterator instead of a list and that it stops when the shortest\n\
930 iterable is exhausted instead of filling in None for shorter\n\
933 static PyTypeObject imap_type
= {
934 PyObject_HEAD_INIT(NULL
)
936 "itertools.imap", /* tp_name */
937 sizeof(imapobject
), /* tp_basicsize */
940 (destructor
)imap_dealloc
, /* tp_dealloc */
946 0, /* tp_as_number */
947 0, /* tp_as_sequence */
948 0, /* tp_as_mapping */
952 PyObject_GenericGetAttr
, /* tp_getattro */
954 0, /* tp_as_buffer */
955 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
956 Py_TPFLAGS_BASETYPE
, /* tp_flags */
957 imap_doc
, /* tp_doc */
958 (traverseproc
)imap_traverse
, /* tp_traverse */
960 0, /* tp_richcompare */
961 0, /* tp_weaklistoffset */
962 PyObject_SelfIter
, /* tp_iter */
963 (iternextfunc
)imap_next
, /* tp_iternext */
969 0, /* tp_descr_get */
970 0, /* tp_descr_set */
971 0, /* tp_dictoffset */
974 imap_new
, /* tp_new */
975 PyObject_GC_Del
, /* tp_free */
979 /* chain object ************************************************************/
984 long iternum
; /* which iterator is active */
985 PyObject
*ittuple
; /* tuple of iterators */
988 static PyTypeObject chain_type
;
991 chain_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
994 int tuplesize
= PySequence_Length(args
);
998 /* obtain iterators */
999 assert(PyTuple_Check(args
));
1000 ittuple
= PyTuple_New(tuplesize
);
1003 for (i
=0; i
< tuplesize
; ++i
) {
1004 PyObject
*item
= PyTuple_GET_ITEM(args
, i
);
1005 PyObject
*it
= PyObject_GetIter(item
);
1007 if (PyErr_ExceptionMatches(PyExc_TypeError
))
1008 PyErr_Format(PyExc_TypeError
,
1009 "chain argument #%d must support iteration",
1014 PyTuple_SET_ITEM(ittuple
, i
, it
);
1017 /* create chainobject structure */
1018 lz
= (chainobject
*)type
->tp_alloc(type
, 0);
1024 lz
->ittuple
= ittuple
;
1026 lz
->tuplesize
= tuplesize
;
1028 return (PyObject
*)lz
;
1032 chain_dealloc(chainobject
*lz
)
1034 PyObject_GC_UnTrack(lz
);
1035 Py_XDECREF(lz
->ittuple
);
1036 lz
->ob_type
->tp_free(lz
);
1040 chain_traverse(chainobject
*lz
, visitproc visit
, void *arg
)
1043 return visit(lz
->ittuple
, arg
);
1048 chain_next(chainobject
*lz
)
1053 while (lz
->iternum
< lz
->tuplesize
) {
1054 it
= PyTuple_GET_ITEM(lz
->ittuple
, lz
->iternum
);
1055 item
= PyIter_Next(it
);
1058 if (PyErr_Occurred()) {
1059 if (PyErr_ExceptionMatches(PyExc_StopIteration
))
1069 PyDoc_STRVAR(chain_doc
,
1070 "chain(*iterables) --> chain object\n\
1072 Return a chain object whose .next() method returns elements from the\n\
1073 first iterable until it is exhausted, then elements from the next\n\
1074 iterable, until all of the iterables are exhausted.");
1076 static PyTypeObject chain_type
= {
1077 PyObject_HEAD_INIT(NULL
)
1079 "itertools.chain", /* tp_name */
1080 sizeof(chainobject
), /* tp_basicsize */
1081 0, /* tp_itemsize */
1083 (destructor
)chain_dealloc
, /* tp_dealloc */
1089 0, /* tp_as_number */
1090 0, /* tp_as_sequence */
1091 0, /* tp_as_mapping */
1095 PyObject_GenericGetAttr
, /* tp_getattro */
1096 0, /* tp_setattro */
1097 0, /* tp_as_buffer */
1098 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1099 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1100 chain_doc
, /* tp_doc */
1101 (traverseproc
)chain_traverse
, /* tp_traverse */
1103 0, /* tp_richcompare */
1104 0, /* tp_weaklistoffset */
1105 PyObject_SelfIter
, /* tp_iter */
1106 (iternextfunc
)chain_next
, /* tp_iternext */
1112 0, /* tp_descr_get */
1113 0, /* tp_descr_set */
1114 0, /* tp_dictoffset */
1117 chain_new
, /* tp_new */
1118 PyObject_GC_Del
, /* tp_free */
1122 /* ifilter object ************************************************************/
1130 static PyTypeObject ifilter_type
;
1133 ifilter_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1135 PyObject
*func
, *seq
;
1139 if (!PyArg_UnpackTuple(args
, "ifilter", 2, 2, &func
, &seq
))
1143 it
= PyObject_GetIter(seq
);
1147 /* create ifilterobject structure */
1148 lz
= (ifilterobject
*)type
->tp_alloc(type
, 0);
1157 return (PyObject
*)lz
;
1161 ifilter_dealloc(ifilterobject
*lz
)
1163 PyObject_GC_UnTrack(lz
);
1164 Py_XDECREF(lz
->func
);
1166 lz
->ob_type
->tp_free(lz
);
1170 ifilter_traverse(ifilterobject
*lz
, visitproc visit
, void *arg
)
1175 err
= visit(lz
->it
, arg
);
1180 err
= visit(lz
->func
, arg
);
1188 ifilter_next(ifilterobject
*lz
)
1191 PyObject
*it
= lz
->it
;
1195 assert(PyIter_Check(it
));
1196 item
= (*it
->ob_type
->tp_iternext
)(it
);
1200 if (lz
->func
== Py_None
) {
1201 ok
= PyObject_IsTrue(item
);
1204 good
= PyObject_CallFunctionObjArgs(lz
->func
,
1210 ok
= PyObject_IsTrue(good
);
1219 PyDoc_STRVAR(ifilter_doc
,
1220 "ifilter(function or None, sequence) --> ifilter object\n\
1222 Return those items of sequence for which function(item) is true.\n\
1223 If function is None, return the items that are true.");
1225 static PyTypeObject ifilter_type
= {
1226 PyObject_HEAD_INIT(NULL
)
1228 "itertools.ifilter", /* tp_name */
1229 sizeof(ifilterobject
), /* tp_basicsize */
1230 0, /* tp_itemsize */
1232 (destructor
)ifilter_dealloc
, /* tp_dealloc */
1238 0, /* tp_as_number */
1239 0, /* tp_as_sequence */
1240 0, /* tp_as_mapping */
1244 PyObject_GenericGetAttr
, /* tp_getattro */
1245 0, /* tp_setattro */
1246 0, /* tp_as_buffer */
1247 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1248 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1249 ifilter_doc
, /* tp_doc */
1250 (traverseproc
)ifilter_traverse
, /* tp_traverse */
1252 0, /* tp_richcompare */
1253 0, /* tp_weaklistoffset */
1254 PyObject_SelfIter
, /* tp_iter */
1255 (iternextfunc
)ifilter_next
, /* tp_iternext */
1261 0, /* tp_descr_get */
1262 0, /* tp_descr_set */
1263 0, /* tp_dictoffset */
1266 ifilter_new
, /* tp_new */
1267 PyObject_GC_Del
, /* tp_free */
1271 /* ifilterfalse object ************************************************************/
1277 } ifilterfalseobject
;
1279 static PyTypeObject ifilterfalse_type
;
1282 ifilterfalse_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1284 PyObject
*func
, *seq
;
1286 ifilterfalseobject
*lz
;
1288 if (!PyArg_UnpackTuple(args
, "ifilterfalse", 2, 2, &func
, &seq
))
1292 it
= PyObject_GetIter(seq
);
1296 /* create ifilterfalseobject structure */
1297 lz
= (ifilterfalseobject
*)type
->tp_alloc(type
, 0);
1306 return (PyObject
*)lz
;
1310 ifilterfalse_dealloc(ifilterfalseobject
*lz
)
1312 PyObject_GC_UnTrack(lz
);
1313 Py_XDECREF(lz
->func
);
1315 lz
->ob_type
->tp_free(lz
);
1319 ifilterfalse_traverse(ifilterfalseobject
*lz
, visitproc visit
, void *arg
)
1324 err
= visit(lz
->it
, arg
);
1329 err
= visit(lz
->func
, arg
);
1337 ifilterfalse_next(ifilterfalseobject
*lz
)
1340 PyObject
*it
= lz
->it
;
1344 assert(PyIter_Check(it
));
1345 item
= (*it
->ob_type
->tp_iternext
)(it
);
1349 if (lz
->func
== Py_None
) {
1350 ok
= PyObject_IsTrue(item
);
1353 good
= PyObject_CallFunctionObjArgs(lz
->func
,
1359 ok
= PyObject_IsTrue(good
);
1368 PyDoc_STRVAR(ifilterfalse_doc
,
1369 "ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1371 Return those items of sequence for which function(item) is false.\n\
1372 If function is None, return the items that are false.");
1374 static PyTypeObject ifilterfalse_type
= {
1375 PyObject_HEAD_INIT(NULL
)
1377 "itertools.ifilterfalse", /* tp_name */
1378 sizeof(ifilterfalseobject
), /* tp_basicsize */
1379 0, /* tp_itemsize */
1381 (destructor
)ifilterfalse_dealloc
, /* tp_dealloc */
1387 0, /* tp_as_number */
1388 0, /* tp_as_sequence */
1389 0, /* tp_as_mapping */
1393 PyObject_GenericGetAttr
, /* tp_getattro */
1394 0, /* tp_setattro */
1395 0, /* tp_as_buffer */
1396 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1397 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1398 ifilterfalse_doc
, /* tp_doc */
1399 (traverseproc
)ifilterfalse_traverse
, /* tp_traverse */
1401 0, /* tp_richcompare */
1402 0, /* tp_weaklistoffset */
1403 PyObject_SelfIter
, /* tp_iter */
1404 (iternextfunc
)ifilterfalse_next
, /* tp_iternext */
1410 0, /* tp_descr_get */
1411 0, /* tp_descr_set */
1412 0, /* tp_dictoffset */
1415 ifilterfalse_new
, /* tp_new */
1416 PyObject_GC_Del
, /* tp_free */
1420 /* count object ************************************************************/
1427 static PyTypeObject count_type
;
1430 count_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1435 if (!PyArg_ParseTuple(args
, "|l:count", &cnt
))
1438 /* create countobject structure */
1439 lz
= (countobject
*)PyObject_New(countobject
, &count_type
);
1444 return (PyObject
*)lz
;
1448 count_next(countobject
*lz
)
1450 return PyInt_FromLong(lz
->cnt
++);
1453 PyDoc_STRVAR(count_doc
,
1454 "count([firstval]) --> count object\n\
1456 Return a count object whose .next() method returns consecutive\n\
1457 integers starting from zero or, if specified, from firstval.");
1459 static PyTypeObject count_type
= {
1460 PyObject_HEAD_INIT(NULL
)
1462 "itertools.count", /* tp_name */
1463 sizeof(countobject
), /* tp_basicsize */
1464 0, /* tp_itemsize */
1466 (destructor
)PyObject_Del
, /* tp_dealloc */
1472 0, /* tp_as_number */
1473 0, /* tp_as_sequence */
1474 0, /* tp_as_mapping */
1478 PyObject_GenericGetAttr
, /* tp_getattro */
1479 0, /* tp_setattro */
1480 0, /* tp_as_buffer */
1481 Py_TPFLAGS_DEFAULT
, /* tp_flags */
1482 count_doc
, /* tp_doc */
1483 0, /* tp_traverse */
1485 0, /* tp_richcompare */
1486 0, /* tp_weaklistoffset */
1487 PyObject_SelfIter
, /* tp_iter */
1488 (iternextfunc
)count_next
, /* tp_iternext */
1494 0, /* tp_descr_get */
1495 0, /* tp_descr_set */
1496 0, /* tp_dictoffset */
1499 count_new
, /* tp_new */
1503 /* izip object ************************************************************/
1510 PyObject
*ittuple
; /* tuple of iterators */
1514 static PyTypeObject izip_type
;
1517 izip_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1521 PyObject
*ittuple
; /* tuple of iterators */
1523 int tuplesize
= PySequence_Length(args
);
1525 /* args must be a tuple */
1526 assert(PyTuple_Check(args
));
1528 /* obtain iterators */
1529 ittuple
= PyTuple_New(tuplesize
);
1532 for (i
=0; i
< tuplesize
; ++i
) {
1533 PyObject
*item
= PyTuple_GET_ITEM(args
, i
);
1534 PyObject
*it
= PyObject_GetIter(item
);
1536 if (PyErr_ExceptionMatches(PyExc_TypeError
))
1537 PyErr_Format(PyExc_TypeError
,
1538 "izip argument #%d must support iteration",
1543 PyTuple_SET_ITEM(ittuple
, i
, it
);
1546 /* create a result holder */
1547 result
= PyTuple_New(tuplesize
);
1548 if (result
== NULL
) {
1552 for (i
=0 ; i
< tuplesize
; i
++) {
1554 PyTuple_SET_ITEM(result
, i
, Py_None
);
1557 /* create izipobject structure */
1558 lz
= (izipobject
*)type
->tp_alloc(type
, 0);
1564 lz
->ittuple
= ittuple
;
1565 lz
->tuplesize
= tuplesize
;
1566 lz
->result
= result
;
1568 return (PyObject
*)lz
;
1572 izip_dealloc(izipobject
*lz
)
1574 PyObject_GC_UnTrack(lz
);
1575 Py_XDECREF(lz
->ittuple
);
1576 Py_XDECREF(lz
->result
);
1577 lz
->ob_type
->tp_free(lz
);
1581 izip_traverse(izipobject
*lz
, visitproc visit
, void *arg
)
1586 err
= visit(lz
->ittuple
, arg
);
1591 err
= visit(lz
->result
, arg
);
1599 izip_next(izipobject
*lz
)
1602 long tuplesize
= lz
->tuplesize
;
1603 PyObject
*result
= lz
->result
;
1610 if (result
->ob_refcnt
== 1) {
1612 for (i
=0 ; i
< tuplesize
; i
++) {
1613 it
= PyTuple_GET_ITEM(lz
->ittuple
, i
);
1614 assert(PyIter_Check(it
));
1615 item
= (*it
->ob_type
->tp_iternext
)(it
);
1620 olditem
= PyTuple_GET_ITEM(result
, i
);
1621 PyTuple_SET_ITEM(result
, i
, item
);
1625 result
= PyTuple_New(tuplesize
);
1628 for (i
=0 ; i
< tuplesize
; i
++) {
1629 it
= PyTuple_GET_ITEM(lz
->ittuple
, i
);
1630 assert(PyIter_Check(it
));
1631 item
= (*it
->ob_type
->tp_iternext
)(it
);
1636 PyTuple_SET_ITEM(result
, i
, item
);
1642 PyDoc_STRVAR(izip_doc
,
1643 "izip(iter1 [,iter2 [...]]) --> izip object\n\
1645 Return a izip object whose .next() method returns a tuple where\n\
1646 the i-th element comes from the i-th iterable argument. The .next()\n\
1647 method continues until the shortest iterable in the argument sequence\n\
1648 is exhausted and then it raises StopIteration. Works like the zip()\n\
1649 function but consumes less memory by returning an iterator instead of\n\
1652 static PyTypeObject izip_type
= {
1653 PyObject_HEAD_INIT(NULL
)
1655 "itertools.izip", /* tp_name */
1656 sizeof(izipobject
), /* tp_basicsize */
1657 0, /* tp_itemsize */
1659 (destructor
)izip_dealloc
, /* tp_dealloc */
1665 0, /* tp_as_number */
1666 0, /* tp_as_sequence */
1667 0, /* tp_as_mapping */
1671 PyObject_GenericGetAttr
, /* tp_getattro */
1672 0, /* tp_setattro */
1673 0, /* tp_as_buffer */
1674 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1675 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1676 izip_doc
, /* tp_doc */
1677 (traverseproc
)izip_traverse
, /* tp_traverse */
1679 0, /* tp_richcompare */
1680 0, /* tp_weaklistoffset */
1681 PyObject_SelfIter
, /* tp_iter */
1682 (iternextfunc
)izip_next
, /* tp_iternext */
1688 0, /* tp_descr_get */
1689 0, /* tp_descr_set */
1690 0, /* tp_dictoffset */
1693 izip_new
, /* tp_new */
1694 PyObject_GC_Del
, /* tp_free */
1698 /* repeat object ************************************************************/
1706 static PyTypeObject repeat_type
;
1709 repeat_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1715 if (!PyArg_ParseTuple(args
, "O|l:repeat", &element
, &cnt
))
1718 if (PyTuple_Size(args
) == 2 && cnt
< 0)
1721 ro
= (repeatobject
*)type
->tp_alloc(type
, 0);
1725 ro
->element
= element
;
1727 return (PyObject
*)ro
;
1731 repeat_dealloc(repeatobject
*ro
)
1733 PyObject_GC_UnTrack(ro
);
1734 Py_XDECREF(ro
->element
);
1735 ro
->ob_type
->tp_free(ro
);
1739 repeat_traverse(repeatobject
*ro
, visitproc visit
, void *arg
)
1742 return visit(ro
->element
, arg
);
1747 repeat_next(repeatobject
*ro
)
1753 Py_INCREF(ro
->element
);
1757 PyDoc_STRVAR(repeat_doc
,
1758 "repeat(element [,times]) -> create an iterator which returns the element\n\
1759 for the specified number of times. If not specified, returns the element\n\
1762 static PyTypeObject repeat_type
= {
1763 PyObject_HEAD_INIT(NULL
)
1765 "itertools.repeat", /* tp_name */
1766 sizeof(repeatobject
), /* tp_basicsize */
1767 0, /* tp_itemsize */
1769 (destructor
)repeat_dealloc
, /* tp_dealloc */
1775 0, /* tp_as_number */
1776 0, /* tp_as_sequence */
1777 0, /* tp_as_mapping */
1781 PyObject_GenericGetAttr
, /* tp_getattro */
1782 0, /* tp_setattro */
1783 0, /* tp_as_buffer */
1784 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1785 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1786 repeat_doc
, /* tp_doc */
1787 (traverseproc
)repeat_traverse
, /* tp_traverse */
1789 0, /* tp_richcompare */
1790 0, /* tp_weaklistoffset */
1791 PyObject_SelfIter
, /* tp_iter */
1792 (iternextfunc
)repeat_next
, /* tp_iternext */
1798 0, /* tp_descr_get */
1799 0, /* tp_descr_set */
1800 0, /* tp_dictoffset */
1803 repeat_new
, /* tp_new */
1804 PyObject_GC_Del
, /* tp_free */
1808 /* module level code ********************************************************/
1810 PyDoc_STRVAR(module_doc
,
1811 "Functional tools for creating and using iterators.\n\
1813 Infinite iterators:\n\
1814 count([n]) --> n, n+1, n+2, ...\n\
1815 cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
1816 repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
1818 Iterators terminating on the shortest input sequence:\n\
1819 izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
1820 ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
1821 ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
1822 islice(seq, [start,] stop [, step]) --> elements from\n\
1823 seq[start:stop:step]\n\
1824 imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
1825 starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
1826 chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
1827 takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
1828 dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
1838 PyTypeObject
*typelist
[] = {
1854 m
= Py_InitModule3("itertools", NULL
, module_doc
);
1856 for (i
=0 ; typelist
[i
] != NULL
; i
++) {
1857 if (PyType_Ready(typelist
[i
]) < 0)
1859 name
= strchr(typelist
[i
]->tp_name
, '.');
1860 assert (name
!= NULL
);
1861 Py_INCREF(typelist
[i
]);
1862 PyModule_AddObject(m
, name
+1, (PyObject
*)typelist
[i
]);