3 #include "structmember.h"
5 /* Itertools module written and maintained
6 by Raymond D. Hettinger <python@rcn.com>
7 Copyright (c) 2003 Python Software Foundation.
12 /* groupby object ***********************************************************/
23 static PyTypeObject groupby_type
;
24 static PyObject
*_grouper_create(groupbyobject
*, PyObject
*);
27 groupby_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
29 static char *kwargs
[] = {"iterable", "key", NULL
};
31 PyObject
*it
, *keyfunc
= Py_None
;
33 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|O:groupby", kwargs
,
37 gbo
= (groupbyobject
*)type
->tp_alloc(type
, 0);
42 gbo
->currvalue
= NULL
;
43 gbo
->keyfunc
= keyfunc
;
45 gbo
->it
= PyObject_GetIter(it
);
46 if (gbo
->it
== NULL
) {
50 return (PyObject
*)gbo
;
54 groupby_dealloc(groupbyobject
*gbo
)
56 PyObject_GC_UnTrack(gbo
);
58 Py_XDECREF(gbo
->keyfunc
);
59 Py_XDECREF(gbo
->tgtkey
);
60 Py_XDECREF(gbo
->currkey
);
61 Py_XDECREF(gbo
->currvalue
);
62 gbo
->ob_type
->tp_free(gbo
);
66 groupby_traverse(groupbyobject
*gbo
, visitproc visit
, void *arg
)
69 Py_VISIT(gbo
->keyfunc
);
70 Py_VISIT(gbo
->tgtkey
);
71 Py_VISIT(gbo
->currkey
);
72 Py_VISIT(gbo
->currvalue
);
77 groupby_next(groupbyobject
*gbo
)
79 PyObject
*newvalue
, *newkey
, *r
, *grouper
, *tmp
;
81 /* skip to next iteration group */
83 if (gbo
->currkey
== NULL
)
85 else if (gbo
->tgtkey
== NULL
)
90 rcmp
= PyObject_RichCompareBool(gbo
->tgtkey
,
98 newvalue
= PyIter_Next(gbo
->it
);
102 if (gbo
->keyfunc
== Py_None
) {
106 newkey
= PyObject_CallFunctionObjArgs(gbo
->keyfunc
,
108 if (newkey
== NULL
) {
115 gbo
->currkey
= newkey
;
118 tmp
= gbo
->currvalue
;
119 gbo
->currvalue
= newvalue
;
123 Py_INCREF(gbo
->currkey
);
125 gbo
->tgtkey
= gbo
->currkey
;
128 grouper
= _grouper_create(gbo
, gbo
->tgtkey
);
132 r
= PyTuple_Pack(2, gbo
->currkey
, grouper
);
137 PyDoc_STRVAR(groupby_doc
,
138 "groupby(iterable[, keyfunc]) -> create an iterator which returns\n\
139 (key, sub-iterator) grouped by each value of key(value).\n");
141 static PyTypeObject groupby_type
= {
142 PyObject_HEAD_INIT(NULL
)
144 "itertools.groupby", /* tp_name */
145 sizeof(groupbyobject
), /* tp_basicsize */
148 (destructor
)groupby_dealloc
, /* tp_dealloc */
154 0, /* tp_as_number */
155 0, /* tp_as_sequence */
156 0, /* tp_as_mapping */
160 PyObject_GenericGetAttr
, /* tp_getattro */
162 0, /* tp_as_buffer */
163 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
164 Py_TPFLAGS_BASETYPE
, /* tp_flags */
165 groupby_doc
, /* tp_doc */
166 (traverseproc
)groupby_traverse
, /* tp_traverse */
168 0, /* tp_richcompare */
169 0, /* tp_weaklistoffset */
170 PyObject_SelfIter
, /* tp_iter */
171 (iternextfunc
)groupby_next
, /* tp_iternext */
177 0, /* tp_descr_get */
178 0, /* tp_descr_set */
179 0, /* tp_dictoffset */
182 groupby_new
, /* tp_new */
183 PyObject_GC_Del
, /* tp_free */
187 /* _grouper object (internal) ************************************************/
195 static PyTypeObject _grouper_type
;
198 _grouper_create(groupbyobject
*parent
, PyObject
*tgtkey
)
202 igo
= PyObject_New(_grouperobject
, &_grouper_type
);
205 igo
->parent
= (PyObject
*)parent
;
207 igo
->tgtkey
= tgtkey
;
210 return (PyObject
*)igo
;
214 _grouper_dealloc(_grouperobject
*igo
)
216 Py_DECREF(igo
->parent
);
217 Py_DECREF(igo
->tgtkey
);
222 _grouper_next(_grouperobject
*igo
)
224 groupbyobject
*gbo
= (groupbyobject
*)igo
->parent
;
225 PyObject
*newvalue
, *newkey
, *r
;
228 if (gbo
->currvalue
== NULL
) {
229 newvalue
= PyIter_Next(gbo
->it
);
230 if (newvalue
== NULL
)
233 if (gbo
->keyfunc
== Py_None
) {
237 newkey
= PyObject_CallFunctionObjArgs(gbo
->keyfunc
,
239 if (newkey
== NULL
) {
245 assert(gbo
->currkey
== NULL
);
246 gbo
->currkey
= newkey
;
247 gbo
->currvalue
= newvalue
;
250 assert(gbo
->currkey
!= NULL
);
251 rcmp
= PyObject_RichCompareBool(igo
->tgtkey
, gbo
->currkey
, Py_EQ
);
253 /* got any error or current group is end */
257 gbo
->currvalue
= NULL
;
258 Py_CLEAR(gbo
->currkey
);
263 static PyTypeObject _grouper_type
= {
264 PyObject_HEAD_INIT(NULL
)
266 "itertools._grouper", /* tp_name */
267 sizeof(_grouperobject
), /* tp_basicsize */
270 (destructor
)_grouper_dealloc
, /* tp_dealloc */
276 0, /* tp_as_number */
277 0, /* tp_as_sequence */
278 0, /* tp_as_mapping */
282 PyObject_GenericGetAttr
, /* tp_getattro */
284 0, /* tp_as_buffer */
285 Py_TPFLAGS_DEFAULT
, /* tp_flags */
289 0, /* tp_richcompare */
290 0, /* tp_weaklistoffset */
291 PyObject_SelfIter
, /* tp_iter */
292 (iternextfunc
)_grouper_next
, /* tp_iternext */
298 0, /* tp_descr_get */
299 0, /* tp_descr_set */
300 0, /* tp_dictoffset */
304 PyObject_Del
, /* tp_free */
309 /* tee object and with supporting function and objects ***************/
311 /* The teedataobject pre-allocates space for LINKCELLS number of objects.
312 To help the object fit neatly inside cache lines (space for 16 to 32
313 pointers), the value should be a multiple of 16 minus space for
314 the other structure members including PyHEAD overhead. The larger the
315 value, the less memory overhead per object and the less time spent
316 allocating/deallocating new links. The smaller the number, the less
317 wasted space and the more rapid freeing of older data.
326 PyObject
*(values
[LINKCELLS
]);
331 teedataobject
*dataobj
;
333 PyObject
*weakreflist
;
336 static PyTypeObject teedataobject_type
;
339 teedataobject_new(PyObject
*it
)
343 tdo
= PyObject_GC_New(teedataobject
, &teedataobject_type
);
348 tdo
->nextlink
= NULL
;
351 PyObject_GC_Track(tdo
);
352 return (PyObject
*)tdo
;
356 teedataobject_jumplink(teedataobject
*tdo
)
358 if (tdo
->nextlink
== NULL
)
359 tdo
->nextlink
= teedataobject_new(tdo
->it
);
360 Py_XINCREF(tdo
->nextlink
);
361 return tdo
->nextlink
;
365 teedataobject_getitem(teedataobject
*tdo
, int i
)
369 assert(i
< LINKCELLS
);
370 if (i
< tdo
->numread
)
371 value
= tdo
->values
[i
];
373 /* this is the lead iterator, so fetch more data */
374 assert(i
== tdo
->numread
);
375 value
= PyIter_Next(tdo
->it
);
379 tdo
->values
[i
] = value
;
386 teedataobject_traverse(teedataobject
*tdo
, visitproc visit
, void * arg
)
390 for (i
= 0; i
< tdo
->numread
; i
++)
391 Py_VISIT(tdo
->values
[i
]);
392 Py_VISIT(tdo
->nextlink
);
397 teedataobject_clear(teedataobject
*tdo
)
401 for (i
=0 ; i
<tdo
->numread
; i
++)
402 Py_CLEAR(tdo
->values
[i
]);
403 Py_CLEAR(tdo
->nextlink
);
408 teedataobject_dealloc(teedataobject
*tdo
)
410 PyObject_GC_UnTrack(tdo
);
411 teedataobject_clear(tdo
);
412 PyObject_GC_Del(tdo
);
415 PyDoc_STRVAR(teedataobject_doc
, "Data container common to multiple tee objects.");
417 static PyTypeObject teedataobject_type
= {
418 PyObject_HEAD_INIT(0) /* Must fill in type value later */
420 "itertools.tee_dataobject", /* tp_name */
421 sizeof(teedataobject
), /* tp_basicsize */
424 (destructor
)teedataobject_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
, /* tp_flags */
440 teedataobject_doc
, /* tp_doc */
441 (traverseproc
)teedataobject_traverse
, /* tp_traverse */
442 (inquiry
)teedataobject_clear
, /* tp_clear */
443 0, /* tp_richcompare */
444 0, /* tp_weaklistoffset */
452 0, /* tp_descr_get */
453 0, /* tp_descr_set */
454 0, /* tp_dictoffset */
458 PyObject_GC_Del
, /* tp_free */
462 static PyTypeObject tee_type
;
465 tee_next(teeobject
*to
)
467 PyObject
*value
, *link
;
469 if (to
->index
>= LINKCELLS
) {
470 link
= teedataobject_jumplink(to
->dataobj
);
471 Py_DECREF(to
->dataobj
);
472 to
->dataobj
= (teedataobject
*)link
;
475 value
= teedataobject_getitem(to
->dataobj
, to
->index
);
483 tee_traverse(teeobject
*to
, visitproc visit
, void *arg
)
485 Py_VISIT((PyObject
*)to
->dataobj
);
490 tee_copy(teeobject
*to
)
494 newto
= PyObject_GC_New(teeobject
, &tee_type
);
497 Py_INCREF(to
->dataobj
);
498 newto
->dataobj
= to
->dataobj
;
499 newto
->index
= to
->index
;
500 newto
->weakreflist
= NULL
;
501 PyObject_GC_Track(newto
);
502 return (PyObject
*)newto
;
505 PyDoc_STRVAR(teecopy_doc
, "Returns an independent iterator.");
508 tee_fromiterable(PyObject
*iterable
)
513 it
= PyObject_GetIter(iterable
);
516 if (PyObject_TypeCheck(it
, &tee_type
)) {
517 to
= (teeobject
*)tee_copy((teeobject
*)it
);
521 to
= PyObject_GC_New(teeobject
, &tee_type
);
524 to
->dataobj
= (teedataobject
*)teedataobject_new(it
);
532 to
->weakreflist
= NULL
;
533 PyObject_GC_Track(to
);
536 return (PyObject
*)to
;
540 tee_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
544 if (!PyArg_UnpackTuple(args
, "tee", 1, 1, &iterable
))
546 return tee_fromiterable(iterable
);
550 tee_clear(teeobject
*to
)
552 if (to
->weakreflist
!= NULL
)
553 PyObject_ClearWeakRefs((PyObject
*) to
);
554 Py_CLEAR(to
->dataobj
);
559 tee_dealloc(teeobject
*to
)
561 PyObject_GC_UnTrack(to
);
566 PyDoc_STRVAR(teeobject_doc
,
567 "Iterator wrapped to make it copyable");
569 static PyMethodDef tee_methods
[] = {
570 {"__copy__", (PyCFunction
)tee_copy
, METH_NOARGS
, teecopy_doc
},
571 {NULL
, NULL
} /* sentinel */
574 static PyTypeObject tee_type
= {
575 PyObject_HEAD_INIT(NULL
)
577 "itertools.tee", /* tp_name */
578 sizeof(teeobject
), /* tp_basicsize */
581 (destructor
)tee_dealloc
, /* tp_dealloc */
587 0, /* tp_as_number */
588 0, /* tp_as_sequence */
589 0, /* tp_as_mapping */
595 0, /* tp_as_buffer */
596 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
, /* tp_flags */
597 teeobject_doc
, /* tp_doc */
598 (traverseproc
)tee_traverse
, /* tp_traverse */
599 (inquiry
)tee_clear
, /* tp_clear */
600 0, /* tp_richcompare */
601 offsetof(teeobject
, weakreflist
), /* tp_weaklistoffset */
602 PyObject_SelfIter
, /* tp_iter */
603 (iternextfunc
)tee_next
, /* tp_iternext */
604 tee_methods
, /* tp_methods */
609 0, /* tp_descr_get */
610 0, /* tp_descr_set */
611 0, /* tp_dictoffset */
614 tee_new
, /* tp_new */
615 PyObject_GC_Del
, /* tp_free */
619 tee(PyObject
*self
, PyObject
*args
)
622 PyObject
*it
, *iterable
, *copyable
, *result
;
624 if (!PyArg_ParseTuple(args
, "O|i", &iterable
, &n
))
626 result
= PyTuple_New(n
);
631 it
= PyObject_GetIter(iterable
);
636 if (!PyObject_HasAttrString(it
, "__copy__")) {
637 copyable
= tee_fromiterable(it
);
639 if (copyable
== NULL
) {
645 PyTuple_SET_ITEM(result
, 0, copyable
);
646 for (i
=1 ; i
<n
; i
++) {
647 copyable
= PyObject_CallMethod(copyable
, "__copy__", NULL
);
648 if (copyable
== NULL
) {
652 PyTuple_SET_ITEM(result
, i
, copyable
);
657 PyDoc_STRVAR(tee_doc
,
658 "tee(iterable, n=2) --> tuple of n independent iterators.");
661 /* cycle object **********************************************************/
670 static PyTypeObject cycle_type
;
673 cycle_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
680 if (!_PyArg_NoKeywords("cycle()", kwds
))
683 if (!PyArg_UnpackTuple(args
, "cycle", 1, 1, &iterable
))
687 it
= PyObject_GetIter(iterable
);
691 saved
= PyList_New(0);
697 /* create cycleobject structure */
698 lz
= (cycleobject
*)type
->tp_alloc(type
, 0);
708 return (PyObject
*)lz
;
712 cycle_dealloc(cycleobject
*lz
)
714 PyObject_GC_UnTrack(lz
);
715 Py_XDECREF(lz
->saved
);
717 lz
->ob_type
->tp_free(lz
);
721 cycle_traverse(cycleobject
*lz
, visitproc visit
, void *arg
)
729 cycle_next(cycleobject
*lz
)
736 item
= PyIter_Next(lz
->it
);
739 PyList_Append(lz
->saved
, item
);
742 if (PyErr_Occurred()) {
743 if (PyErr_ExceptionMatches(PyExc_StopIteration
))
748 if (PyList_Size(lz
->saved
) == 0)
750 it
= PyObject_GetIter(lz
->saved
);
760 PyDoc_STRVAR(cycle_doc
,
761 "cycle(iterable) --> cycle object\n\
763 Return elements from the iterable until it is exhausted.\n\
764 Then repeat the sequence indefinitely.");
766 static PyTypeObject cycle_type
= {
767 PyObject_HEAD_INIT(NULL
)
769 "itertools.cycle", /* tp_name */
770 sizeof(cycleobject
), /* tp_basicsize */
773 (destructor
)cycle_dealloc
, /* tp_dealloc */
779 0, /* tp_as_number */
780 0, /* tp_as_sequence */
781 0, /* tp_as_mapping */
785 PyObject_GenericGetAttr
, /* tp_getattro */
787 0, /* tp_as_buffer */
788 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
789 Py_TPFLAGS_BASETYPE
, /* tp_flags */
790 cycle_doc
, /* tp_doc */
791 (traverseproc
)cycle_traverse
, /* tp_traverse */
793 0, /* tp_richcompare */
794 0, /* tp_weaklistoffset */
795 PyObject_SelfIter
, /* tp_iter */
796 (iternextfunc
)cycle_next
, /* tp_iternext */
802 0, /* tp_descr_get */
803 0, /* tp_descr_set */
804 0, /* tp_dictoffset */
807 cycle_new
, /* tp_new */
808 PyObject_GC_Del
, /* tp_free */
812 /* dropwhile object **********************************************************/
821 static PyTypeObject dropwhile_type
;
824 dropwhile_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
826 PyObject
*func
, *seq
;
830 if (!_PyArg_NoKeywords("dropwhile()", kwds
))
833 if (!PyArg_UnpackTuple(args
, "dropwhile", 2, 2, &func
, &seq
))
837 it
= PyObject_GetIter(seq
);
841 /* create dropwhileobject structure */
842 lz
= (dropwhileobject
*)type
->tp_alloc(type
, 0);
852 return (PyObject
*)lz
;
856 dropwhile_dealloc(dropwhileobject
*lz
)
858 PyObject_GC_UnTrack(lz
);
859 Py_XDECREF(lz
->func
);
861 lz
->ob_type
->tp_free(lz
);
865 dropwhile_traverse(dropwhileobject
*lz
, visitproc visit
, void *arg
)
873 dropwhile_next(dropwhileobject
*lz
)
875 PyObject
*item
, *good
;
876 PyObject
*it
= lz
->it
;
878 PyObject
*(*iternext
)(PyObject
*);
880 assert(PyIter_Check(it
));
881 iternext
= *it
->ob_type
->tp_iternext
;
889 good
= PyObject_CallFunctionObjArgs(lz
->func
, item
, NULL
);
894 ok
= PyObject_IsTrue(good
);
904 PyDoc_STRVAR(dropwhile_doc
,
905 "dropwhile(predicate, iterable) --> dropwhile object\n\
907 Drop items from the iterable while predicate(item) is true.\n\
908 Afterwards, return every element until the iterable is exhausted.");
910 static PyTypeObject dropwhile_type
= {
911 PyObject_HEAD_INIT(NULL
)
913 "itertools.dropwhile", /* tp_name */
914 sizeof(dropwhileobject
), /* tp_basicsize */
917 (destructor
)dropwhile_dealloc
, /* tp_dealloc */
923 0, /* tp_as_number */
924 0, /* tp_as_sequence */
925 0, /* tp_as_mapping */
929 PyObject_GenericGetAttr
, /* tp_getattro */
931 0, /* tp_as_buffer */
932 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
933 Py_TPFLAGS_BASETYPE
, /* tp_flags */
934 dropwhile_doc
, /* tp_doc */
935 (traverseproc
)dropwhile_traverse
, /* tp_traverse */
937 0, /* tp_richcompare */
938 0, /* tp_weaklistoffset */
939 PyObject_SelfIter
, /* tp_iter */
940 (iternextfunc
)dropwhile_next
, /* tp_iternext */
946 0, /* tp_descr_get */
947 0, /* tp_descr_set */
948 0, /* tp_dictoffset */
951 dropwhile_new
, /* tp_new */
952 PyObject_GC_Del
, /* tp_free */
956 /* takewhile object **********************************************************/
965 static PyTypeObject takewhile_type
;
968 takewhile_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
970 PyObject
*func
, *seq
;
974 if (!_PyArg_NoKeywords("takewhile()", kwds
))
977 if (!PyArg_UnpackTuple(args
, "takewhile", 2, 2, &func
, &seq
))
981 it
= PyObject_GetIter(seq
);
985 /* create takewhileobject structure */
986 lz
= (takewhileobject
*)type
->tp_alloc(type
, 0);
996 return (PyObject
*)lz
;
1000 takewhile_dealloc(takewhileobject
*lz
)
1002 PyObject_GC_UnTrack(lz
);
1003 Py_XDECREF(lz
->func
);
1005 lz
->ob_type
->tp_free(lz
);
1009 takewhile_traverse(takewhileobject
*lz
, visitproc visit
, void *arg
)
1017 takewhile_next(takewhileobject
*lz
)
1019 PyObject
*item
, *good
;
1020 PyObject
*it
= lz
->it
;
1026 assert(PyIter_Check(it
));
1027 item
= (*it
->ob_type
->tp_iternext
)(it
);
1031 good
= PyObject_CallFunctionObjArgs(lz
->func
, item
, NULL
);
1036 ok
= PyObject_IsTrue(good
);
1045 PyDoc_STRVAR(takewhile_doc
,
1046 "takewhile(predicate, iterable) --> takewhile object\n\
1048 Return successive entries from an iterable as long as the \n\
1049 predicate evaluates to true for each entry.");
1051 static PyTypeObject takewhile_type
= {
1052 PyObject_HEAD_INIT(NULL
)
1054 "itertools.takewhile", /* tp_name */
1055 sizeof(takewhileobject
), /* tp_basicsize */
1056 0, /* tp_itemsize */
1058 (destructor
)takewhile_dealloc
, /* tp_dealloc */
1064 0, /* tp_as_number */
1065 0, /* tp_as_sequence */
1066 0, /* tp_as_mapping */
1070 PyObject_GenericGetAttr
, /* tp_getattro */
1071 0, /* tp_setattro */
1072 0, /* tp_as_buffer */
1073 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1074 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1075 takewhile_doc
, /* tp_doc */
1076 (traverseproc
)takewhile_traverse
, /* tp_traverse */
1078 0, /* tp_richcompare */
1079 0, /* tp_weaklistoffset */
1080 PyObject_SelfIter
, /* tp_iter */
1081 (iternextfunc
)takewhile_next
, /* tp_iternext */
1087 0, /* tp_descr_get */
1088 0, /* tp_descr_set */
1089 0, /* tp_dictoffset */
1092 takewhile_new
, /* tp_new */
1093 PyObject_GC_Del
, /* tp_free */
1097 /* islice object ************************************************************/
1108 static PyTypeObject islice_type
;
1111 islice_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1114 Py_ssize_t start
=0, stop
=-1, step
=1;
1115 PyObject
*it
, *a1
=NULL
, *a2
=NULL
, *a3
=NULL
;
1119 if (!_PyArg_NoKeywords("islice()", kwds
))
1122 if (!PyArg_UnpackTuple(args
, "islice", 2, 4, &seq
, &a1
, &a2
, &a3
))
1125 numargs
= PyTuple_Size(args
);
1127 if (a1
!= Py_None
) {
1128 stop
= PyInt_AsSsize_t(a1
);
1130 if (PyErr_Occurred())
1132 PyErr_SetString(PyExc_ValueError
,
1133 "Stop argument for islice() must be a non-negative integer or None.");
1139 start
= PyInt_AsSsize_t(a1
);
1140 if (start
== -1 && PyErr_Occurred())
1142 if (a2
!= Py_None
) {
1143 stop
= PyInt_AsSsize_t(a2
);
1145 if (PyErr_Occurred())
1147 PyErr_SetString(PyExc_ValueError
,
1148 "Stop argument for islice() must be a non-negative integer or None.");
1153 if (start
<0 || stop
<-1) {
1154 PyErr_SetString(PyExc_ValueError
,
1155 "Indices for islice() must be non-negative integers or None.");
1161 step
= PyInt_AsSsize_t(a3
);
1162 if (step
== -1 && PyErr_Occurred())
1166 PyErr_SetString(PyExc_ValueError
,
1167 "Step for islice() must be a positive integer or None.");
1172 it
= PyObject_GetIter(seq
);
1176 /* create isliceobject structure */
1177 lz
= (isliceobject
*)type
->tp_alloc(type
, 0);
1188 return (PyObject
*)lz
;
1192 islice_dealloc(isliceobject
*lz
)
1194 PyObject_GC_UnTrack(lz
);
1196 lz
->ob_type
->tp_free(lz
);
1200 islice_traverse(isliceobject
*lz
, visitproc visit
, void *arg
)
1207 islice_next(isliceobject
*lz
)
1210 PyObject
*it
= lz
->it
;
1212 PyObject
*(*iternext
)(PyObject
*);
1214 assert(PyIter_Check(it
));
1215 iternext
= *it
->ob_type
->tp_iternext
;
1216 while (lz
->cnt
< lz
->next
) {
1217 item
= iternext(it
);
1223 if (lz
->stop
!= -1 && lz
->cnt
>= lz
->stop
)
1225 assert(PyIter_Check(it
));
1226 item
= iternext(it
);
1231 lz
->next
+= lz
->step
;
1232 if (lz
->next
< oldnext
) /* Check for overflow */
1233 lz
->next
= lz
->stop
;
1237 PyDoc_STRVAR(islice_doc
,
1238 "islice(iterable, [start,] stop [, step]) --> islice object\n\
1240 Return an iterator whose next() method returns selected values from an\n\
1241 iterable. If start is specified, will skip all preceding elements;\n\
1242 otherwise, start defaults to zero. Step defaults to one. If\n\
1243 specified as another value, step determines how many values are \n\
1244 skipped between successive calls. Works like a slice() on a list\n\
1245 but returns an iterator.");
1247 static PyTypeObject islice_type
= {
1248 PyObject_HEAD_INIT(NULL
)
1250 "itertools.islice", /* tp_name */
1251 sizeof(isliceobject
), /* tp_basicsize */
1252 0, /* tp_itemsize */
1254 (destructor
)islice_dealloc
, /* tp_dealloc */
1260 0, /* tp_as_number */
1261 0, /* tp_as_sequence */
1262 0, /* tp_as_mapping */
1266 PyObject_GenericGetAttr
, /* tp_getattro */
1267 0, /* tp_setattro */
1268 0, /* tp_as_buffer */
1269 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1270 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1271 islice_doc
, /* tp_doc */
1272 (traverseproc
)islice_traverse
, /* tp_traverse */
1274 0, /* tp_richcompare */
1275 0, /* tp_weaklistoffset */
1276 PyObject_SelfIter
, /* tp_iter */
1277 (iternextfunc
)islice_next
, /* tp_iternext */
1283 0, /* tp_descr_get */
1284 0, /* tp_descr_set */
1285 0, /* tp_dictoffset */
1288 islice_new
, /* tp_new */
1289 PyObject_GC_Del
, /* tp_free */
1293 /* starmap object ************************************************************/
1301 static PyTypeObject starmap_type
;
1304 starmap_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1306 PyObject
*func
, *seq
;
1310 if (!_PyArg_NoKeywords("starmap()", kwds
))
1313 if (!PyArg_UnpackTuple(args
, "starmap", 2, 2, &func
, &seq
))
1317 it
= PyObject_GetIter(seq
);
1321 /* create starmapobject structure */
1322 lz
= (starmapobject
*)type
->tp_alloc(type
, 0);
1331 return (PyObject
*)lz
;
1335 starmap_dealloc(starmapobject
*lz
)
1337 PyObject_GC_UnTrack(lz
);
1338 Py_XDECREF(lz
->func
);
1340 lz
->ob_type
->tp_free(lz
);
1344 starmap_traverse(starmapobject
*lz
, visitproc visit
, void *arg
)
1352 starmap_next(starmapobject
*lz
)
1356 PyObject
*it
= lz
->it
;
1358 assert(PyIter_Check(it
));
1359 args
= (*it
->ob_type
->tp_iternext
)(it
);
1362 if (!PyTuple_CheckExact(args
)) {
1364 PyErr_SetString(PyExc_TypeError
,
1365 "iterator must return a tuple");
1368 result
= PyObject_Call(lz
->func
, args
, NULL
);
1373 PyDoc_STRVAR(starmap_doc
,
1374 "starmap(function, sequence) --> starmap object\n\
1376 Return an iterator whose values are returned from the function evaluated\n\
1377 with a argument tuple taken from the given sequence.");
1379 static PyTypeObject starmap_type
= {
1380 PyObject_HEAD_INIT(NULL
)
1382 "itertools.starmap", /* tp_name */
1383 sizeof(starmapobject
), /* tp_basicsize */
1384 0, /* tp_itemsize */
1386 (destructor
)starmap_dealloc
, /* tp_dealloc */
1392 0, /* tp_as_number */
1393 0, /* tp_as_sequence */
1394 0, /* tp_as_mapping */
1398 PyObject_GenericGetAttr
, /* tp_getattro */
1399 0, /* tp_setattro */
1400 0, /* tp_as_buffer */
1401 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1402 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1403 starmap_doc
, /* tp_doc */
1404 (traverseproc
)starmap_traverse
, /* tp_traverse */
1406 0, /* tp_richcompare */
1407 0, /* tp_weaklistoffset */
1408 PyObject_SelfIter
, /* tp_iter */
1409 (iternextfunc
)starmap_next
, /* tp_iternext */
1415 0, /* tp_descr_get */
1416 0, /* tp_descr_set */
1417 0, /* tp_dictoffset */
1420 starmap_new
, /* tp_new */
1421 PyObject_GC_Del
, /* tp_free */
1425 /* imap object ************************************************************/
1433 static PyTypeObject imap_type
;
1436 imap_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1438 PyObject
*it
, *iters
, *func
;
1440 Py_ssize_t numargs
, i
;
1442 if (!_PyArg_NoKeywords("imap()", kwds
))
1445 numargs
= PyTuple_Size(args
);
1447 PyErr_SetString(PyExc_TypeError
,
1448 "imap() must have at least two arguments.");
1452 iters
= PyTuple_New(numargs
-1);
1456 for (i
=1 ; i
<numargs
; i
++) {
1458 it
= PyObject_GetIter(PyTuple_GET_ITEM(args
, i
));
1463 PyTuple_SET_ITEM(iters
, i
-1, it
);
1466 /* create imapobject structure */
1467 lz
= (imapobject
*)type
->tp_alloc(type
, 0);
1473 func
= PyTuple_GET_ITEM(args
, 0);
1477 return (PyObject
*)lz
;
1481 imap_dealloc(imapobject
*lz
)
1483 PyObject_GC_UnTrack(lz
);
1484 Py_XDECREF(lz
->iters
);
1485 Py_XDECREF(lz
->func
);
1486 lz
->ob_type
->tp_free(lz
);
1490 imap_traverse(imapobject
*lz
, visitproc visit
, void *arg
)
1492 Py_VISIT(lz
->iters
);
1498 imap() is an iterator version of __builtins__.map() except that it does
1499 not have the None fill-in feature. That was intentionally left out for
1500 the following reasons:
1502 1) Itertools are designed to be easily combined and chained together.
1503 Having all tools stop with the shortest input is a unifying principle
1504 that makes it easier to combine finite iterators (supplying data) with
1505 infinite iterators like count() and repeat() (for supplying sequential
1506 or constant arguments to a function).
1508 2) In typical use cases for combining itertools, having one finite data
1509 supplier run out before another is likely to be an error condition which
1510 should not pass silently by automatically supplying None.
1512 3) The use cases for automatic None fill-in are rare -- not many functions
1513 do something useful when a parameter suddenly switches type and becomes
1516 4) If a need does arise, it can be met by __builtins__.map() or by
1517 writing: chain(iterable, repeat(None)).
1519 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
1523 imap_next(imapobject
*lz
)
1528 Py_ssize_t numargs
, i
;
1530 numargs
= PyTuple_Size(lz
->iters
);
1531 argtuple
= PyTuple_New(numargs
);
1532 if (argtuple
== NULL
)
1535 for (i
=0 ; i
<numargs
; i
++) {
1536 val
= PyIter_Next(PyTuple_GET_ITEM(lz
->iters
, i
));
1538 Py_DECREF(argtuple
);
1541 PyTuple_SET_ITEM(argtuple
, i
, val
);
1543 if (lz
->func
== Py_None
)
1545 result
= PyObject_Call(lz
->func
, argtuple
, NULL
);
1546 Py_DECREF(argtuple
);
1550 PyDoc_STRVAR(imap_doc
,
1551 "imap(func, *iterables) --> imap object\n\
1553 Make an iterator that computes the function using arguments from\n\
1554 each of the iterables. Like map() except that it returns\n\
1555 an iterator instead of a list and that it stops when the shortest\n\
1556 iterable is exhausted instead of filling in None for shorter\n\
1559 static PyTypeObject imap_type
= {
1560 PyObject_HEAD_INIT(NULL
)
1562 "itertools.imap", /* tp_name */
1563 sizeof(imapobject
), /* tp_basicsize */
1564 0, /* tp_itemsize */
1566 (destructor
)imap_dealloc
, /* tp_dealloc */
1572 0, /* tp_as_number */
1573 0, /* tp_as_sequence */
1574 0, /* tp_as_mapping */
1578 PyObject_GenericGetAttr
, /* tp_getattro */
1579 0, /* tp_setattro */
1580 0, /* tp_as_buffer */
1581 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1582 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1583 imap_doc
, /* tp_doc */
1584 (traverseproc
)imap_traverse
, /* tp_traverse */
1586 0, /* tp_richcompare */
1587 0, /* tp_weaklistoffset */
1588 PyObject_SelfIter
, /* tp_iter */
1589 (iternextfunc
)imap_next
, /* tp_iternext */
1595 0, /* tp_descr_get */
1596 0, /* tp_descr_set */
1597 0, /* tp_dictoffset */
1600 imap_new
, /* tp_new */
1601 PyObject_GC_Del
, /* tp_free */
1605 /* chain object ************************************************************/
1609 Py_ssize_t tuplesize
;
1610 Py_ssize_t iternum
; /* which iterator is active */
1611 PyObject
*ittuple
; /* tuple of iterators */
1614 static PyTypeObject chain_type
;
1617 chain_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1620 Py_ssize_t tuplesize
= PySequence_Length(args
);
1624 if (!_PyArg_NoKeywords("chain()", kwds
))
1627 /* obtain iterators */
1628 assert(PyTuple_Check(args
));
1629 ittuple
= PyTuple_New(tuplesize
);
1630 if (ittuple
== NULL
)
1632 for (i
=0; i
< tuplesize
; ++i
) {
1633 PyObject
*item
= PyTuple_GET_ITEM(args
, i
);
1634 PyObject
*it
= PyObject_GetIter(item
);
1636 if (PyErr_ExceptionMatches(PyExc_TypeError
))
1637 PyErr_Format(PyExc_TypeError
,
1638 "chain argument #%zd must support iteration",
1643 PyTuple_SET_ITEM(ittuple
, i
, it
);
1646 /* create chainobject structure */
1647 lz
= (chainobject
*)type
->tp_alloc(type
, 0);
1653 lz
->ittuple
= ittuple
;
1655 lz
->tuplesize
= tuplesize
;
1657 return (PyObject
*)lz
;
1661 chain_dealloc(chainobject
*lz
)
1663 PyObject_GC_UnTrack(lz
);
1664 Py_XDECREF(lz
->ittuple
);
1665 lz
->ob_type
->tp_free(lz
);
1669 chain_traverse(chainobject
*lz
, visitproc visit
, void *arg
)
1671 Py_VISIT(lz
->ittuple
);
1676 chain_next(chainobject
*lz
)
1681 while (lz
->iternum
< lz
->tuplesize
) {
1682 it
= PyTuple_GET_ITEM(lz
->ittuple
, lz
->iternum
);
1683 item
= PyIter_Next(it
);
1686 if (PyErr_Occurred()) {
1687 if (PyErr_ExceptionMatches(PyExc_StopIteration
))
1697 PyDoc_STRVAR(chain_doc
,
1698 "chain(*iterables) --> chain object\n\
1700 Return a chain object whose .next() method returns elements from the\n\
1701 first iterable until it is exhausted, then elements from the next\n\
1702 iterable, until all of the iterables are exhausted.");
1704 static PyTypeObject chain_type
= {
1705 PyObject_HEAD_INIT(NULL
)
1707 "itertools.chain", /* tp_name */
1708 sizeof(chainobject
), /* tp_basicsize */
1709 0, /* tp_itemsize */
1711 (destructor
)chain_dealloc
, /* tp_dealloc */
1717 0, /* tp_as_number */
1718 0, /* tp_as_sequence */
1719 0, /* tp_as_mapping */
1723 PyObject_GenericGetAttr
, /* tp_getattro */
1724 0, /* tp_setattro */
1725 0, /* tp_as_buffer */
1726 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1727 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1728 chain_doc
, /* tp_doc */
1729 (traverseproc
)chain_traverse
, /* tp_traverse */
1731 0, /* tp_richcompare */
1732 0, /* tp_weaklistoffset */
1733 PyObject_SelfIter
, /* tp_iter */
1734 (iternextfunc
)chain_next
, /* tp_iternext */
1740 0, /* tp_descr_get */
1741 0, /* tp_descr_set */
1742 0, /* tp_dictoffset */
1745 chain_new
, /* tp_new */
1746 PyObject_GC_Del
, /* tp_free */
1750 /* ifilter object ************************************************************/
1758 static PyTypeObject ifilter_type
;
1761 ifilter_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1763 PyObject
*func
, *seq
;
1767 if (!_PyArg_NoKeywords("ifilter()", kwds
))
1770 if (!PyArg_UnpackTuple(args
, "ifilter", 2, 2, &func
, &seq
))
1774 it
= PyObject_GetIter(seq
);
1778 /* create ifilterobject structure */
1779 lz
= (ifilterobject
*)type
->tp_alloc(type
, 0);
1788 return (PyObject
*)lz
;
1792 ifilter_dealloc(ifilterobject
*lz
)
1794 PyObject_GC_UnTrack(lz
);
1795 Py_XDECREF(lz
->func
);
1797 lz
->ob_type
->tp_free(lz
);
1801 ifilter_traverse(ifilterobject
*lz
, visitproc visit
, void *arg
)
1809 ifilter_next(ifilterobject
*lz
)
1812 PyObject
*it
= lz
->it
;
1814 PyObject
*(*iternext
)(PyObject
*);
1816 assert(PyIter_Check(it
));
1817 iternext
= *it
->ob_type
->tp_iternext
;
1819 item
= iternext(it
);
1823 if (lz
->func
== Py_None
) {
1824 ok
= PyObject_IsTrue(item
);
1827 good
= PyObject_CallFunctionObjArgs(lz
->func
,
1833 ok
= PyObject_IsTrue(good
);
1842 PyDoc_STRVAR(ifilter_doc
,
1843 "ifilter(function or None, sequence) --> ifilter object\n\
1845 Return those items of sequence for which function(item) is true.\n\
1846 If function is None, return the items that are true.");
1848 static PyTypeObject ifilter_type
= {
1849 PyObject_HEAD_INIT(NULL
)
1851 "itertools.ifilter", /* tp_name */
1852 sizeof(ifilterobject
), /* tp_basicsize */
1853 0, /* tp_itemsize */
1855 (destructor
)ifilter_dealloc
, /* tp_dealloc */
1861 0, /* tp_as_number */
1862 0, /* tp_as_sequence */
1863 0, /* tp_as_mapping */
1867 PyObject_GenericGetAttr
, /* tp_getattro */
1868 0, /* tp_setattro */
1869 0, /* tp_as_buffer */
1870 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1871 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1872 ifilter_doc
, /* tp_doc */
1873 (traverseproc
)ifilter_traverse
, /* tp_traverse */
1875 0, /* tp_richcompare */
1876 0, /* tp_weaklistoffset */
1877 PyObject_SelfIter
, /* tp_iter */
1878 (iternextfunc
)ifilter_next
, /* tp_iternext */
1884 0, /* tp_descr_get */
1885 0, /* tp_descr_set */
1886 0, /* tp_dictoffset */
1889 ifilter_new
, /* tp_new */
1890 PyObject_GC_Del
, /* tp_free */
1894 /* ifilterfalse object ************************************************************/
1900 } ifilterfalseobject
;
1902 static PyTypeObject ifilterfalse_type
;
1905 ifilterfalse_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1907 PyObject
*func
, *seq
;
1909 ifilterfalseobject
*lz
;
1911 if (!_PyArg_NoKeywords("ifilterfalse()", kwds
))
1914 if (!PyArg_UnpackTuple(args
, "ifilterfalse", 2, 2, &func
, &seq
))
1918 it
= PyObject_GetIter(seq
);
1922 /* create ifilterfalseobject structure */
1923 lz
= (ifilterfalseobject
*)type
->tp_alloc(type
, 0);
1932 return (PyObject
*)lz
;
1936 ifilterfalse_dealloc(ifilterfalseobject
*lz
)
1938 PyObject_GC_UnTrack(lz
);
1939 Py_XDECREF(lz
->func
);
1941 lz
->ob_type
->tp_free(lz
);
1945 ifilterfalse_traverse(ifilterfalseobject
*lz
, visitproc visit
, void *arg
)
1953 ifilterfalse_next(ifilterfalseobject
*lz
)
1956 PyObject
*it
= lz
->it
;
1958 PyObject
*(*iternext
)(PyObject
*);
1960 assert(PyIter_Check(it
));
1961 iternext
= *it
->ob_type
->tp_iternext
;
1963 item
= iternext(it
);
1967 if (lz
->func
== Py_None
) {
1968 ok
= PyObject_IsTrue(item
);
1971 good
= PyObject_CallFunctionObjArgs(lz
->func
,
1977 ok
= PyObject_IsTrue(good
);
1986 PyDoc_STRVAR(ifilterfalse_doc
,
1987 "ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1989 Return those items of sequence for which function(item) is false.\n\
1990 If function is None, return the items that are false.");
1992 static PyTypeObject ifilterfalse_type
= {
1993 PyObject_HEAD_INIT(NULL
)
1995 "itertools.ifilterfalse", /* tp_name */
1996 sizeof(ifilterfalseobject
), /* tp_basicsize */
1997 0, /* tp_itemsize */
1999 (destructor
)ifilterfalse_dealloc
, /* tp_dealloc */
2005 0, /* tp_as_number */
2006 0, /* tp_as_sequence */
2007 0, /* tp_as_mapping */
2011 PyObject_GenericGetAttr
, /* tp_getattro */
2012 0, /* tp_setattro */
2013 0, /* tp_as_buffer */
2014 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
2015 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2016 ifilterfalse_doc
, /* tp_doc */
2017 (traverseproc
)ifilterfalse_traverse
, /* tp_traverse */
2019 0, /* tp_richcompare */
2020 0, /* tp_weaklistoffset */
2021 PyObject_SelfIter
, /* tp_iter */
2022 (iternextfunc
)ifilterfalse_next
, /* tp_iternext */
2028 0, /* tp_descr_get */
2029 0, /* tp_descr_set */
2030 0, /* tp_dictoffset */
2033 ifilterfalse_new
, /* tp_new */
2034 PyObject_GC_Del
, /* tp_free */
2038 /* count object ************************************************************/
2045 static PyTypeObject count_type
;
2048 count_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
2053 if (!_PyArg_NoKeywords("count()", kwds
))
2056 if (!PyArg_ParseTuple(args
, "|n:count", &cnt
))
2059 /* create countobject structure */
2060 lz
= (countobject
*)PyObject_New(countobject
, &count_type
);
2065 return (PyObject
*)lz
;
2069 count_next(countobject
*lz
)
2071 return PyInt_FromSize_t(lz
->cnt
++);
2075 count_repr(countobject
*lz
)
2077 return PyString_FromFormat("count(%zd)", lz
->cnt
);
2080 PyDoc_STRVAR(count_doc
,
2081 "count([firstval]) --> count object\n\
2083 Return a count object whose .next() method returns consecutive\n\
2084 integers starting from zero or, if specified, from firstval.");
2086 static PyTypeObject count_type
= {
2087 PyObject_HEAD_INIT(NULL
)
2089 "itertools.count", /* tp_name */
2090 sizeof(countobject
), /* tp_basicsize */
2091 0, /* tp_itemsize */
2093 (destructor
)PyObject_Del
, /* tp_dealloc */
2098 (reprfunc
)count_repr
, /* tp_repr */
2099 0, /* tp_as_number */
2100 0, /* tp_as_sequence */
2101 0, /* tp_as_mapping */
2105 PyObject_GenericGetAttr
, /* tp_getattro */
2106 0, /* tp_setattro */
2107 0, /* tp_as_buffer */
2108 Py_TPFLAGS_DEFAULT
, /* tp_flags */
2109 count_doc
, /* tp_doc */
2110 0, /* tp_traverse */
2112 0, /* tp_richcompare */
2113 0, /* tp_weaklistoffset */
2114 PyObject_SelfIter
, /* tp_iter */
2115 (iternextfunc
)count_next
, /* tp_iternext */
2121 0, /* tp_descr_get */
2122 0, /* tp_descr_set */
2123 0, /* tp_dictoffset */
2126 count_new
, /* tp_new */
2130 /* izip object ************************************************************/
2136 Py_ssize_t tuplesize
;
2137 PyObject
*ittuple
; /* tuple of iterators */
2141 static PyTypeObject izip_type
;
2144 izip_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
2148 PyObject
*ittuple
; /* tuple of iterators */
2150 Py_ssize_t tuplesize
= PySequence_Length(args
);
2152 if (!_PyArg_NoKeywords("izip()", kwds
))
2155 /* args must be a tuple */
2156 assert(PyTuple_Check(args
));
2158 /* obtain iterators */
2159 ittuple
= PyTuple_New(tuplesize
);
2160 if (ittuple
== NULL
)
2162 for (i
=0; i
< tuplesize
; ++i
) {
2163 PyObject
*item
= PyTuple_GET_ITEM(args
, i
);
2164 PyObject
*it
= PyObject_GetIter(item
);
2166 if (PyErr_ExceptionMatches(PyExc_TypeError
))
2167 PyErr_Format(PyExc_TypeError
,
2168 "izip argument #%zd must support iteration",
2173 PyTuple_SET_ITEM(ittuple
, i
, it
);
2176 /* create a result holder */
2177 result
= PyTuple_New(tuplesize
);
2178 if (result
== NULL
) {
2182 for (i
=0 ; i
< tuplesize
; i
++) {
2184 PyTuple_SET_ITEM(result
, i
, Py_None
);
2187 /* create izipobject structure */
2188 lz
= (izipobject
*)type
->tp_alloc(type
, 0);
2194 lz
->ittuple
= ittuple
;
2195 lz
->tuplesize
= tuplesize
;
2196 lz
->result
= result
;
2198 return (PyObject
*)lz
;
2202 izip_dealloc(izipobject
*lz
)
2204 PyObject_GC_UnTrack(lz
);
2205 Py_XDECREF(lz
->ittuple
);
2206 Py_XDECREF(lz
->result
);
2207 lz
->ob_type
->tp_free(lz
);
2211 izip_traverse(izipobject
*lz
, visitproc visit
, void *arg
)
2213 Py_VISIT(lz
->ittuple
);
2214 Py_VISIT(lz
->result
);
2219 izip_next(izipobject
*lz
)
2222 Py_ssize_t tuplesize
= lz
->tuplesize
;
2223 PyObject
*result
= lz
->result
;
2230 if (result
->ob_refcnt
== 1) {
2232 for (i
=0 ; i
< tuplesize
; i
++) {
2233 it
= PyTuple_GET_ITEM(lz
->ittuple
, i
);
2234 assert(PyIter_Check(it
));
2235 item
= (*it
->ob_type
->tp_iternext
)(it
);
2240 olditem
= PyTuple_GET_ITEM(result
, i
);
2241 PyTuple_SET_ITEM(result
, i
, item
);
2245 result
= PyTuple_New(tuplesize
);
2248 for (i
=0 ; i
< tuplesize
; i
++) {
2249 it
= PyTuple_GET_ITEM(lz
->ittuple
, i
);
2250 assert(PyIter_Check(it
));
2251 item
= (*it
->ob_type
->tp_iternext
)(it
);
2256 PyTuple_SET_ITEM(result
, i
, item
);
2262 PyDoc_STRVAR(izip_doc
,
2263 "izip(iter1 [,iter2 [...]]) --> izip object\n\
2265 Return a izip object whose .next() method returns a tuple where\n\
2266 the i-th element comes from the i-th iterable argument. The .next()\n\
2267 method continues until the shortest iterable in the argument sequence\n\
2268 is exhausted and then it raises StopIteration. Works like the zip()\n\
2269 function but consumes less memory by returning an iterator instead of\n\
2272 static PyTypeObject izip_type
= {
2273 PyObject_HEAD_INIT(NULL
)
2275 "itertools.izip", /* tp_name */
2276 sizeof(izipobject
), /* tp_basicsize */
2277 0, /* tp_itemsize */
2279 (destructor
)izip_dealloc
, /* tp_dealloc */
2285 0, /* tp_as_number */
2286 0, /* tp_as_sequence */
2287 0, /* tp_as_mapping */
2291 PyObject_GenericGetAttr
, /* tp_getattro */
2292 0, /* tp_setattro */
2293 0, /* tp_as_buffer */
2294 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
2295 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2296 izip_doc
, /* tp_doc */
2297 (traverseproc
)izip_traverse
, /* tp_traverse */
2299 0, /* tp_richcompare */
2300 0, /* tp_weaklistoffset */
2301 PyObject_SelfIter
, /* tp_iter */
2302 (iternextfunc
)izip_next
, /* tp_iternext */
2308 0, /* tp_descr_get */
2309 0, /* tp_descr_set */
2310 0, /* tp_dictoffset */
2313 izip_new
, /* tp_new */
2314 PyObject_GC_Del
, /* tp_free */
2318 /* repeat object ************************************************************/
2326 static PyTypeObject repeat_type
;
2329 repeat_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
2333 Py_ssize_t cnt
= -1;
2335 if (!_PyArg_NoKeywords("repeat()", kwds
))
2338 if (!PyArg_ParseTuple(args
, "O|n:repeat", &element
, &cnt
))
2341 if (PyTuple_Size(args
) == 2 && cnt
< 0)
2344 ro
= (repeatobject
*)type
->tp_alloc(type
, 0);
2348 ro
->element
= element
;
2350 return (PyObject
*)ro
;
2354 repeat_dealloc(repeatobject
*ro
)
2356 PyObject_GC_UnTrack(ro
);
2357 Py_XDECREF(ro
->element
);
2358 ro
->ob_type
->tp_free(ro
);
2362 repeat_traverse(repeatobject
*ro
, visitproc visit
, void *arg
)
2364 Py_VISIT(ro
->element
);
2369 repeat_next(repeatobject
*ro
)
2375 Py_INCREF(ro
->element
);
2380 repeat_repr(repeatobject
*ro
)
2382 PyObject
*result
, *objrepr
;
2384 objrepr
= PyObject_Repr(ro
->element
);
2385 if (objrepr
== NULL
)
2389 result
= PyString_FromFormat("repeat(%s)",
2390 PyString_AS_STRING(objrepr
));
2392 result
= PyString_FromFormat("repeat(%s, %zd)",
2393 PyString_AS_STRING(objrepr
), ro
->cnt
);
2399 repeat_len(repeatobject
*ro
)
2401 if (ro
->cnt
== -1) {
2402 PyErr_SetString(PyExc_TypeError
, "len() of unsized object");
2405 return PyInt_FromSize_t(ro
->cnt
);
2408 PyDoc_STRVAR(length_hint_doc
, "Private method returning an estimate of len(list(it)).");
2410 static PyMethodDef repeat_methods
[] = {
2411 {"__length_hint__", (PyCFunction
)repeat_len
, METH_NOARGS
, length_hint_doc
},
2412 {NULL
, NULL
} /* sentinel */
2415 PyDoc_STRVAR(repeat_doc
,
2416 "repeat(element [,times]) -> create an iterator which returns the element\n\
2417 for the specified number of times. If not specified, returns the element\n\
2420 static PyTypeObject repeat_type
= {
2421 PyObject_HEAD_INIT(NULL
)
2423 "itertools.repeat", /* tp_name */
2424 sizeof(repeatobject
), /* tp_basicsize */
2425 0, /* tp_itemsize */
2427 (destructor
)repeat_dealloc
, /* tp_dealloc */
2432 (reprfunc
)repeat_repr
, /* tp_repr */
2433 0, /* tp_as_number */
2434 0, /* tp_as_sequence */
2435 0, /* tp_as_mapping */
2439 PyObject_GenericGetAttr
, /* tp_getattro */
2440 0, /* tp_setattro */
2441 0, /* tp_as_buffer */
2442 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
2443 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2444 repeat_doc
, /* tp_doc */
2445 (traverseproc
)repeat_traverse
, /* tp_traverse */
2447 0, /* tp_richcompare */
2448 0, /* tp_weaklistoffset */
2449 PyObject_SelfIter
, /* tp_iter */
2450 (iternextfunc
)repeat_next
, /* tp_iternext */
2451 repeat_methods
, /* tp_methods */
2456 0, /* tp_descr_get */
2457 0, /* tp_descr_set */
2458 0, /* tp_dictoffset */
2461 repeat_new
, /* tp_new */
2462 PyObject_GC_Del
, /* tp_free */
2466 /* module level code ********************************************************/
2468 PyDoc_STRVAR(module_doc
,
2469 "Functional tools for creating and using iterators.\n\
2471 Infinite iterators:\n\
2472 count([n]) --> n, n+1, n+2, ...\n\
2473 cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
2474 repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
2476 Iterators terminating on the shortest input sequence:\n\
2477 izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
2478 ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
2479 ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
2480 islice(seq, [start,] stop [, step]) --> elements from\n\
2481 seq[start:stop:step]\n\
2482 imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
2483 starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
2484 tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
2485 chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
2486 takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
2487 dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
2488 groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\
2492 static PyMethodDef module_methods
[] = {
2493 {"tee", (PyCFunction
)tee
, METH_VARARGS
, tee_doc
},
2494 {NULL
, NULL
} /* sentinel */
2503 PyTypeObject
*typelist
[] = {
2520 teedataobject_type
.ob_type
= &PyType_Type
;
2521 m
= Py_InitModule3("itertools", module_methods
, module_doc
);
2525 for (i
=0 ; typelist
[i
] != NULL
; i
++) {
2526 if (PyType_Ready(typelist
[i
]) < 0)
2528 name
= strchr(typelist
[i
]->tp_name
, '.');
2529 assert (name
!= NULL
);
2530 Py_INCREF(typelist
[i
]);
2531 PyModule_AddObject(m
, name
+1, (PyObject
*)typelist
[i
]);
2534 if (PyType_Ready(&teedataobject_type
) < 0)
2536 if (PyType_Ready(&tee_type
) < 0)
2538 if (PyType_Ready(&_grouper_type
) < 0)