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_INCREF(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_XDECREF(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
);
526 to
->weakreflist
= NULL
;
527 PyObject_GC_Track(to
);
530 return (PyObject
*)to
;
534 tee_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
538 if (!PyArg_UnpackTuple(args
, "tee", 1, 1, &iterable
))
540 return tee_fromiterable(iterable
);
544 tee_clear(teeobject
*to
)
546 if (to
->weakreflist
!= NULL
)
547 PyObject_ClearWeakRefs((PyObject
*) to
);
548 Py_CLEAR(to
->dataobj
);
553 tee_dealloc(teeobject
*to
)
555 PyObject_GC_UnTrack(to
);
560 PyDoc_STRVAR(teeobject_doc
,
561 "Iterator wrapped to make it copyable");
563 static PyMethodDef tee_methods
[] = {
564 {"__copy__", (PyCFunction
)tee_copy
, METH_NOARGS
, teecopy_doc
},
565 {NULL
, NULL
} /* sentinel */
568 static PyTypeObject tee_type
= {
569 PyObject_HEAD_INIT(NULL
)
571 "itertools.tee", /* tp_name */
572 sizeof(teeobject
), /* tp_basicsize */
575 (destructor
)tee_dealloc
, /* tp_dealloc */
581 0, /* tp_as_number */
582 0, /* tp_as_sequence */
583 0, /* tp_as_mapping */
589 0, /* tp_as_buffer */
590 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
, /* tp_flags */
591 teeobject_doc
, /* tp_doc */
592 (traverseproc
)tee_traverse
, /* tp_traverse */
593 (inquiry
)tee_clear
, /* tp_clear */
594 0, /* tp_richcompare */
595 offsetof(teeobject
, weakreflist
), /* tp_weaklistoffset */
596 PyObject_SelfIter
, /* tp_iter */
597 (iternextfunc
)tee_next
, /* tp_iternext */
598 tee_methods
, /* tp_methods */
603 0, /* tp_descr_get */
604 0, /* tp_descr_set */
605 0, /* tp_dictoffset */
608 tee_new
, /* tp_new */
609 PyObject_GC_Del
, /* tp_free */
613 tee(PyObject
*self
, PyObject
*args
)
616 PyObject
*it
, *iterable
, *copyable
, *result
;
618 if (!PyArg_ParseTuple(args
, "O|i", &iterable
, &n
))
620 result
= PyTuple_New(n
);
625 it
= PyObject_GetIter(iterable
);
630 if (!PyObject_HasAttrString(it
, "__copy__")) {
631 copyable
= tee_fromiterable(it
);
633 if (copyable
== NULL
) {
639 PyTuple_SET_ITEM(result
, 0, copyable
);
640 for (i
=1 ; i
<n
; i
++) {
641 copyable
= PyObject_CallMethod(copyable
, "__copy__", NULL
);
642 if (copyable
== NULL
) {
646 PyTuple_SET_ITEM(result
, i
, copyable
);
651 PyDoc_STRVAR(tee_doc
,
652 "tee(iterable, n=2) --> tuple of n independent iterators.");
655 /* cycle object **********************************************************/
664 static PyTypeObject cycle_type
;
667 cycle_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
674 if (!_PyArg_NoKeywords("cycle()", kwds
))
677 if (!PyArg_UnpackTuple(args
, "cycle", 1, 1, &iterable
))
681 it
= PyObject_GetIter(iterable
);
685 saved
= PyList_New(0);
691 /* create cycleobject structure */
692 lz
= (cycleobject
*)type
->tp_alloc(type
, 0);
702 return (PyObject
*)lz
;
706 cycle_dealloc(cycleobject
*lz
)
708 PyObject_GC_UnTrack(lz
);
709 Py_XDECREF(lz
->saved
);
711 lz
->ob_type
->tp_free(lz
);
715 cycle_traverse(cycleobject
*lz
, visitproc visit
, void *arg
)
723 cycle_next(cycleobject
*lz
)
730 item
= PyIter_Next(lz
->it
);
733 PyList_Append(lz
->saved
, item
);
736 if (PyErr_Occurred()) {
737 if (PyErr_ExceptionMatches(PyExc_StopIteration
))
742 if (PyList_Size(lz
->saved
) == 0)
744 it
= PyObject_GetIter(lz
->saved
);
754 PyDoc_STRVAR(cycle_doc
,
755 "cycle(iterable) --> cycle object\n\
757 Return elements from the iterable until it is exhausted.\n\
758 Then repeat the sequence indefinitely.");
760 static PyTypeObject cycle_type
= {
761 PyObject_HEAD_INIT(NULL
)
763 "itertools.cycle", /* tp_name */
764 sizeof(cycleobject
), /* tp_basicsize */
767 (destructor
)cycle_dealloc
, /* tp_dealloc */
773 0, /* tp_as_number */
774 0, /* tp_as_sequence */
775 0, /* tp_as_mapping */
779 PyObject_GenericGetAttr
, /* tp_getattro */
781 0, /* tp_as_buffer */
782 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
783 Py_TPFLAGS_BASETYPE
, /* tp_flags */
784 cycle_doc
, /* tp_doc */
785 (traverseproc
)cycle_traverse
, /* tp_traverse */
787 0, /* tp_richcompare */
788 0, /* tp_weaklistoffset */
789 PyObject_SelfIter
, /* tp_iter */
790 (iternextfunc
)cycle_next
, /* tp_iternext */
796 0, /* tp_descr_get */
797 0, /* tp_descr_set */
798 0, /* tp_dictoffset */
801 cycle_new
, /* tp_new */
802 PyObject_GC_Del
, /* tp_free */
806 /* dropwhile object **********************************************************/
815 static PyTypeObject dropwhile_type
;
818 dropwhile_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
820 PyObject
*func
, *seq
;
824 if (!_PyArg_NoKeywords("dropwhile()", kwds
))
827 if (!PyArg_UnpackTuple(args
, "dropwhile", 2, 2, &func
, &seq
))
831 it
= PyObject_GetIter(seq
);
835 /* create dropwhileobject structure */
836 lz
= (dropwhileobject
*)type
->tp_alloc(type
, 0);
846 return (PyObject
*)lz
;
850 dropwhile_dealloc(dropwhileobject
*lz
)
852 PyObject_GC_UnTrack(lz
);
853 Py_XDECREF(lz
->func
);
855 lz
->ob_type
->tp_free(lz
);
859 dropwhile_traverse(dropwhileobject
*lz
, visitproc visit
, void *arg
)
867 dropwhile_next(dropwhileobject
*lz
)
869 PyObject
*item
, *good
;
870 PyObject
*it
= lz
->it
;
872 PyObject
*(*iternext
)(PyObject
*);
874 assert(PyIter_Check(it
));
875 iternext
= *it
->ob_type
->tp_iternext
;
883 good
= PyObject_CallFunctionObjArgs(lz
->func
, item
, NULL
);
888 ok
= PyObject_IsTrue(good
);
898 PyDoc_STRVAR(dropwhile_doc
,
899 "dropwhile(predicate, iterable) --> dropwhile object\n\
901 Drop items from the iterable while predicate(item) is true.\n\
902 Afterwards, return every element until the iterable is exhausted.");
904 static PyTypeObject dropwhile_type
= {
905 PyObject_HEAD_INIT(NULL
)
907 "itertools.dropwhile", /* tp_name */
908 sizeof(dropwhileobject
), /* tp_basicsize */
911 (destructor
)dropwhile_dealloc
, /* tp_dealloc */
917 0, /* tp_as_number */
918 0, /* tp_as_sequence */
919 0, /* tp_as_mapping */
923 PyObject_GenericGetAttr
, /* tp_getattro */
925 0, /* tp_as_buffer */
926 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
927 Py_TPFLAGS_BASETYPE
, /* tp_flags */
928 dropwhile_doc
, /* tp_doc */
929 (traverseproc
)dropwhile_traverse
, /* tp_traverse */
931 0, /* tp_richcompare */
932 0, /* tp_weaklistoffset */
933 PyObject_SelfIter
, /* tp_iter */
934 (iternextfunc
)dropwhile_next
, /* tp_iternext */
940 0, /* tp_descr_get */
941 0, /* tp_descr_set */
942 0, /* tp_dictoffset */
945 dropwhile_new
, /* tp_new */
946 PyObject_GC_Del
, /* tp_free */
950 /* takewhile object **********************************************************/
959 static PyTypeObject takewhile_type
;
962 takewhile_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
964 PyObject
*func
, *seq
;
968 if (!_PyArg_NoKeywords("takewhile()", kwds
))
971 if (!PyArg_UnpackTuple(args
, "takewhile", 2, 2, &func
, &seq
))
975 it
= PyObject_GetIter(seq
);
979 /* create takewhileobject structure */
980 lz
= (takewhileobject
*)type
->tp_alloc(type
, 0);
990 return (PyObject
*)lz
;
994 takewhile_dealloc(takewhileobject
*lz
)
996 PyObject_GC_UnTrack(lz
);
997 Py_XDECREF(lz
->func
);
999 lz
->ob_type
->tp_free(lz
);
1003 takewhile_traverse(takewhileobject
*lz
, visitproc visit
, void *arg
)
1011 takewhile_next(takewhileobject
*lz
)
1013 PyObject
*item
, *good
;
1014 PyObject
*it
= lz
->it
;
1020 assert(PyIter_Check(it
));
1021 item
= (*it
->ob_type
->tp_iternext
)(it
);
1025 good
= PyObject_CallFunctionObjArgs(lz
->func
, item
, NULL
);
1030 ok
= PyObject_IsTrue(good
);
1039 PyDoc_STRVAR(takewhile_doc
,
1040 "takewhile(predicate, iterable) --> takewhile object\n\
1042 Return successive entries from an iterable as long as the \n\
1043 predicate evaluates to true for each entry.");
1045 static PyTypeObject takewhile_type
= {
1046 PyObject_HEAD_INIT(NULL
)
1048 "itertools.takewhile", /* tp_name */
1049 sizeof(takewhileobject
), /* tp_basicsize */
1050 0, /* tp_itemsize */
1052 (destructor
)takewhile_dealloc
, /* tp_dealloc */
1058 0, /* tp_as_number */
1059 0, /* tp_as_sequence */
1060 0, /* tp_as_mapping */
1064 PyObject_GenericGetAttr
, /* tp_getattro */
1065 0, /* tp_setattro */
1066 0, /* tp_as_buffer */
1067 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1068 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1069 takewhile_doc
, /* tp_doc */
1070 (traverseproc
)takewhile_traverse
, /* tp_traverse */
1072 0, /* tp_richcompare */
1073 0, /* tp_weaklistoffset */
1074 PyObject_SelfIter
, /* tp_iter */
1075 (iternextfunc
)takewhile_next
, /* tp_iternext */
1081 0, /* tp_descr_get */
1082 0, /* tp_descr_set */
1083 0, /* tp_dictoffset */
1086 takewhile_new
, /* tp_new */
1087 PyObject_GC_Del
, /* tp_free */
1091 /* islice object ************************************************************/
1102 static PyTypeObject islice_type
;
1105 islice_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1108 Py_ssize_t start
=0, stop
=-1, step
=1;
1109 PyObject
*it
, *a1
=NULL
, *a2
=NULL
, *a3
=NULL
;
1113 if (!_PyArg_NoKeywords("islice()", kwds
))
1116 if (!PyArg_UnpackTuple(args
, "islice", 2, 4, &seq
, &a1
, &a2
, &a3
))
1119 numargs
= PyTuple_Size(args
);
1121 if (a1
!= Py_None
) {
1122 stop
= PyInt_AsSsize_t(a1
);
1124 if (PyErr_Occurred())
1126 PyErr_SetString(PyExc_ValueError
,
1127 "Stop argument for islice() must be a non-negative integer or None.");
1133 start
= PyInt_AsSsize_t(a1
);
1134 if (start
== -1 && PyErr_Occurred())
1136 if (a2
!= Py_None
) {
1137 stop
= PyInt_AsSsize_t(a2
);
1139 if (PyErr_Occurred())
1141 PyErr_SetString(PyExc_ValueError
,
1142 "Stop argument for islice() must be a non-negative integer or None.");
1147 if (start
<0 || stop
<-1) {
1148 PyErr_SetString(PyExc_ValueError
,
1149 "Indices for islice() must be non-negative integers or None.");
1155 step
= PyInt_AsSsize_t(a3
);
1156 if (step
== -1 && PyErr_Occurred())
1160 PyErr_SetString(PyExc_ValueError
,
1161 "Step for islice() must be a positive integer or None.");
1166 it
= PyObject_GetIter(seq
);
1170 /* create isliceobject structure */
1171 lz
= (isliceobject
*)type
->tp_alloc(type
, 0);
1182 return (PyObject
*)lz
;
1186 islice_dealloc(isliceobject
*lz
)
1188 PyObject_GC_UnTrack(lz
);
1190 lz
->ob_type
->tp_free(lz
);
1194 islice_traverse(isliceobject
*lz
, visitproc visit
, void *arg
)
1201 islice_next(isliceobject
*lz
)
1204 PyObject
*it
= lz
->it
;
1206 PyObject
*(*iternext
)(PyObject
*);
1208 assert(PyIter_Check(it
));
1209 iternext
= *it
->ob_type
->tp_iternext
;
1210 while (lz
->cnt
< lz
->next
) {
1211 item
= iternext(it
);
1217 if (lz
->stop
!= -1 && lz
->cnt
>= lz
->stop
)
1219 assert(PyIter_Check(it
));
1220 item
= iternext(it
);
1225 lz
->next
+= lz
->step
;
1226 if (lz
->next
< oldnext
) /* Check for overflow */
1227 lz
->next
= lz
->stop
;
1231 PyDoc_STRVAR(islice_doc
,
1232 "islice(iterable, [start,] stop [, step]) --> islice object\n\
1234 Return an iterator whose next() method returns selected values from an\n\
1235 iterable. If start is specified, will skip all preceding elements;\n\
1236 otherwise, start defaults to zero. Step defaults to one. If\n\
1237 specified as another value, step determines how many values are \n\
1238 skipped between successive calls. Works like a slice() on a list\n\
1239 but returns an iterator.");
1241 static PyTypeObject islice_type
= {
1242 PyObject_HEAD_INIT(NULL
)
1244 "itertools.islice", /* tp_name */
1245 sizeof(isliceobject
), /* tp_basicsize */
1246 0, /* tp_itemsize */
1248 (destructor
)islice_dealloc
, /* tp_dealloc */
1254 0, /* tp_as_number */
1255 0, /* tp_as_sequence */
1256 0, /* tp_as_mapping */
1260 PyObject_GenericGetAttr
, /* tp_getattro */
1261 0, /* tp_setattro */
1262 0, /* tp_as_buffer */
1263 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1264 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1265 islice_doc
, /* tp_doc */
1266 (traverseproc
)islice_traverse
, /* tp_traverse */
1268 0, /* tp_richcompare */
1269 0, /* tp_weaklistoffset */
1270 PyObject_SelfIter
, /* tp_iter */
1271 (iternextfunc
)islice_next
, /* tp_iternext */
1277 0, /* tp_descr_get */
1278 0, /* tp_descr_set */
1279 0, /* tp_dictoffset */
1282 islice_new
, /* tp_new */
1283 PyObject_GC_Del
, /* tp_free */
1287 /* starmap object ************************************************************/
1295 static PyTypeObject starmap_type
;
1298 starmap_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1300 PyObject
*func
, *seq
;
1304 if (!_PyArg_NoKeywords("starmap()", kwds
))
1307 if (!PyArg_UnpackTuple(args
, "starmap", 2, 2, &func
, &seq
))
1311 it
= PyObject_GetIter(seq
);
1315 /* create starmapobject structure */
1316 lz
= (starmapobject
*)type
->tp_alloc(type
, 0);
1325 return (PyObject
*)lz
;
1329 starmap_dealloc(starmapobject
*lz
)
1331 PyObject_GC_UnTrack(lz
);
1332 Py_XDECREF(lz
->func
);
1334 lz
->ob_type
->tp_free(lz
);
1338 starmap_traverse(starmapobject
*lz
, visitproc visit
, void *arg
)
1346 starmap_next(starmapobject
*lz
)
1350 PyObject
*it
= lz
->it
;
1352 assert(PyIter_Check(it
));
1353 args
= (*it
->ob_type
->tp_iternext
)(it
);
1356 if (!PyTuple_CheckExact(args
)) {
1358 PyErr_SetString(PyExc_TypeError
,
1359 "iterator must return a tuple");
1362 result
= PyObject_Call(lz
->func
, args
, NULL
);
1367 PyDoc_STRVAR(starmap_doc
,
1368 "starmap(function, sequence) --> starmap object\n\
1370 Return an iterator whose values are returned from the function evaluated\n\
1371 with a argument tuple taken from the given sequence.");
1373 static PyTypeObject starmap_type
= {
1374 PyObject_HEAD_INIT(NULL
)
1376 "itertools.starmap", /* tp_name */
1377 sizeof(starmapobject
), /* tp_basicsize */
1378 0, /* tp_itemsize */
1380 (destructor
)starmap_dealloc
, /* tp_dealloc */
1386 0, /* tp_as_number */
1387 0, /* tp_as_sequence */
1388 0, /* tp_as_mapping */
1392 PyObject_GenericGetAttr
, /* tp_getattro */
1393 0, /* tp_setattro */
1394 0, /* tp_as_buffer */
1395 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1396 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1397 starmap_doc
, /* tp_doc */
1398 (traverseproc
)starmap_traverse
, /* tp_traverse */
1400 0, /* tp_richcompare */
1401 0, /* tp_weaklistoffset */
1402 PyObject_SelfIter
, /* tp_iter */
1403 (iternextfunc
)starmap_next
, /* tp_iternext */
1409 0, /* tp_descr_get */
1410 0, /* tp_descr_set */
1411 0, /* tp_dictoffset */
1414 starmap_new
, /* tp_new */
1415 PyObject_GC_Del
, /* tp_free */
1419 /* imap object ************************************************************/
1427 static PyTypeObject imap_type
;
1430 imap_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1432 PyObject
*it
, *iters
, *func
;
1434 Py_ssize_t numargs
, i
;
1436 if (!_PyArg_NoKeywords("imap()", kwds
))
1439 numargs
= PyTuple_Size(args
);
1441 PyErr_SetString(PyExc_TypeError
,
1442 "imap() must have at least two arguments.");
1446 iters
= PyTuple_New(numargs
-1);
1450 for (i
=1 ; i
<numargs
; i
++) {
1452 it
= PyObject_GetIter(PyTuple_GET_ITEM(args
, i
));
1457 PyTuple_SET_ITEM(iters
, i
-1, it
);
1460 /* create imapobject structure */
1461 lz
= (imapobject
*)type
->tp_alloc(type
, 0);
1467 func
= PyTuple_GET_ITEM(args
, 0);
1471 return (PyObject
*)lz
;
1475 imap_dealloc(imapobject
*lz
)
1477 PyObject_GC_UnTrack(lz
);
1478 Py_XDECREF(lz
->iters
);
1479 Py_XDECREF(lz
->func
);
1480 lz
->ob_type
->tp_free(lz
);
1484 imap_traverse(imapobject
*lz
, visitproc visit
, void *arg
)
1486 Py_VISIT(lz
->iters
);
1492 imap() is an iterator version of __builtins__.map() except that it does
1493 not have the None fill-in feature. That was intentionally left out for
1494 the following reasons:
1496 1) Itertools are designed to be easily combined and chained together.
1497 Having all tools stop with the shortest input is a unifying principle
1498 that makes it easier to combine finite iterators (supplying data) with
1499 infinite iterators like count() and repeat() (for supplying sequential
1500 or constant arguments to a function).
1502 2) In typical use cases for combining itertools, having one finite data
1503 supplier run out before another is likely to be an error condition which
1504 should not pass silently by automatically supplying None.
1506 3) The use cases for automatic None fill-in are rare -- not many functions
1507 do something useful when a parameter suddenly switches type and becomes
1510 4) If a need does arise, it can be met by __builtins__.map() or by
1511 writing: chain(iterable, repeat(None)).
1513 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
1517 imap_next(imapobject
*lz
)
1522 Py_ssize_t numargs
, i
;
1524 numargs
= PyTuple_Size(lz
->iters
);
1525 argtuple
= PyTuple_New(numargs
);
1526 if (argtuple
== NULL
)
1529 for (i
=0 ; i
<numargs
; i
++) {
1530 val
= PyIter_Next(PyTuple_GET_ITEM(lz
->iters
, i
));
1532 Py_DECREF(argtuple
);
1535 PyTuple_SET_ITEM(argtuple
, i
, val
);
1537 if (lz
->func
== Py_None
)
1539 result
= PyObject_Call(lz
->func
, argtuple
, NULL
);
1540 Py_DECREF(argtuple
);
1544 PyDoc_STRVAR(imap_doc
,
1545 "imap(func, *iterables) --> imap object\n\
1547 Make an iterator that computes the function using arguments from\n\
1548 each of the iterables. Like map() except that it returns\n\
1549 an iterator instead of a list and that it stops when the shortest\n\
1550 iterable is exhausted instead of filling in None for shorter\n\
1553 static PyTypeObject imap_type
= {
1554 PyObject_HEAD_INIT(NULL
)
1556 "itertools.imap", /* tp_name */
1557 sizeof(imapobject
), /* tp_basicsize */
1558 0, /* tp_itemsize */
1560 (destructor
)imap_dealloc
, /* tp_dealloc */
1566 0, /* tp_as_number */
1567 0, /* tp_as_sequence */
1568 0, /* tp_as_mapping */
1572 PyObject_GenericGetAttr
, /* tp_getattro */
1573 0, /* tp_setattro */
1574 0, /* tp_as_buffer */
1575 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1576 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1577 imap_doc
, /* tp_doc */
1578 (traverseproc
)imap_traverse
, /* tp_traverse */
1580 0, /* tp_richcompare */
1581 0, /* tp_weaklistoffset */
1582 PyObject_SelfIter
, /* tp_iter */
1583 (iternextfunc
)imap_next
, /* tp_iternext */
1589 0, /* tp_descr_get */
1590 0, /* tp_descr_set */
1591 0, /* tp_dictoffset */
1594 imap_new
, /* tp_new */
1595 PyObject_GC_Del
, /* tp_free */
1599 /* chain object ************************************************************/
1603 Py_ssize_t tuplesize
;
1604 Py_ssize_t iternum
; /* which iterator is active */
1605 PyObject
*ittuple
; /* tuple of iterators */
1608 static PyTypeObject chain_type
;
1611 chain_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1614 Py_ssize_t tuplesize
= PySequence_Length(args
);
1618 if (!_PyArg_NoKeywords("chain()", kwds
))
1621 /* obtain iterators */
1622 assert(PyTuple_Check(args
));
1623 ittuple
= PyTuple_New(tuplesize
);
1624 if (ittuple
== NULL
)
1626 for (i
=0; i
< tuplesize
; ++i
) {
1627 PyObject
*item
= PyTuple_GET_ITEM(args
, i
);
1628 PyObject
*it
= PyObject_GetIter(item
);
1630 if (PyErr_ExceptionMatches(PyExc_TypeError
))
1631 PyErr_Format(PyExc_TypeError
,
1632 "chain argument #%zd must support iteration",
1637 PyTuple_SET_ITEM(ittuple
, i
, it
);
1640 /* create chainobject structure */
1641 lz
= (chainobject
*)type
->tp_alloc(type
, 0);
1647 lz
->ittuple
= ittuple
;
1649 lz
->tuplesize
= tuplesize
;
1651 return (PyObject
*)lz
;
1655 chain_dealloc(chainobject
*lz
)
1657 PyObject_GC_UnTrack(lz
);
1658 Py_XDECREF(lz
->ittuple
);
1659 lz
->ob_type
->tp_free(lz
);
1663 chain_traverse(chainobject
*lz
, visitproc visit
, void *arg
)
1665 Py_VISIT(lz
->ittuple
);
1670 chain_next(chainobject
*lz
)
1675 while (lz
->iternum
< lz
->tuplesize
) {
1676 it
= PyTuple_GET_ITEM(lz
->ittuple
, lz
->iternum
);
1677 item
= PyIter_Next(it
);
1680 if (PyErr_Occurred()) {
1681 if (PyErr_ExceptionMatches(PyExc_StopIteration
))
1691 PyDoc_STRVAR(chain_doc
,
1692 "chain(*iterables) --> chain object\n\
1694 Return a chain object whose .next() method returns elements from the\n\
1695 first iterable until it is exhausted, then elements from the next\n\
1696 iterable, until all of the iterables are exhausted.");
1698 static PyTypeObject chain_type
= {
1699 PyObject_HEAD_INIT(NULL
)
1701 "itertools.chain", /* tp_name */
1702 sizeof(chainobject
), /* tp_basicsize */
1703 0, /* tp_itemsize */
1705 (destructor
)chain_dealloc
, /* tp_dealloc */
1711 0, /* tp_as_number */
1712 0, /* tp_as_sequence */
1713 0, /* tp_as_mapping */
1717 PyObject_GenericGetAttr
, /* tp_getattro */
1718 0, /* tp_setattro */
1719 0, /* tp_as_buffer */
1720 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1721 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1722 chain_doc
, /* tp_doc */
1723 (traverseproc
)chain_traverse
, /* tp_traverse */
1725 0, /* tp_richcompare */
1726 0, /* tp_weaklistoffset */
1727 PyObject_SelfIter
, /* tp_iter */
1728 (iternextfunc
)chain_next
, /* tp_iternext */
1734 0, /* tp_descr_get */
1735 0, /* tp_descr_set */
1736 0, /* tp_dictoffset */
1739 chain_new
, /* tp_new */
1740 PyObject_GC_Del
, /* tp_free */
1744 /* ifilter object ************************************************************/
1752 static PyTypeObject ifilter_type
;
1755 ifilter_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1757 PyObject
*func
, *seq
;
1761 if (!_PyArg_NoKeywords("ifilter()", kwds
))
1764 if (!PyArg_UnpackTuple(args
, "ifilter", 2, 2, &func
, &seq
))
1768 it
= PyObject_GetIter(seq
);
1772 /* create ifilterobject structure */
1773 lz
= (ifilterobject
*)type
->tp_alloc(type
, 0);
1782 return (PyObject
*)lz
;
1786 ifilter_dealloc(ifilterobject
*lz
)
1788 PyObject_GC_UnTrack(lz
);
1789 Py_XDECREF(lz
->func
);
1791 lz
->ob_type
->tp_free(lz
);
1795 ifilter_traverse(ifilterobject
*lz
, visitproc visit
, void *arg
)
1803 ifilter_next(ifilterobject
*lz
)
1806 PyObject
*it
= lz
->it
;
1808 PyObject
*(*iternext
)(PyObject
*);
1810 assert(PyIter_Check(it
));
1811 iternext
= *it
->ob_type
->tp_iternext
;
1813 item
= iternext(it
);
1817 if (lz
->func
== Py_None
) {
1818 ok
= PyObject_IsTrue(item
);
1821 good
= PyObject_CallFunctionObjArgs(lz
->func
,
1827 ok
= PyObject_IsTrue(good
);
1836 PyDoc_STRVAR(ifilter_doc
,
1837 "ifilter(function or None, sequence) --> ifilter object\n\
1839 Return those items of sequence for which function(item) is true.\n\
1840 If function is None, return the items that are true.");
1842 static PyTypeObject ifilter_type
= {
1843 PyObject_HEAD_INIT(NULL
)
1845 "itertools.ifilter", /* tp_name */
1846 sizeof(ifilterobject
), /* tp_basicsize */
1847 0, /* tp_itemsize */
1849 (destructor
)ifilter_dealloc
, /* tp_dealloc */
1855 0, /* tp_as_number */
1856 0, /* tp_as_sequence */
1857 0, /* tp_as_mapping */
1861 PyObject_GenericGetAttr
, /* tp_getattro */
1862 0, /* tp_setattro */
1863 0, /* tp_as_buffer */
1864 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
1865 Py_TPFLAGS_BASETYPE
, /* tp_flags */
1866 ifilter_doc
, /* tp_doc */
1867 (traverseproc
)ifilter_traverse
, /* tp_traverse */
1869 0, /* tp_richcompare */
1870 0, /* tp_weaklistoffset */
1871 PyObject_SelfIter
, /* tp_iter */
1872 (iternextfunc
)ifilter_next
, /* tp_iternext */
1878 0, /* tp_descr_get */
1879 0, /* tp_descr_set */
1880 0, /* tp_dictoffset */
1883 ifilter_new
, /* tp_new */
1884 PyObject_GC_Del
, /* tp_free */
1888 /* ifilterfalse object ************************************************************/
1894 } ifilterfalseobject
;
1896 static PyTypeObject ifilterfalse_type
;
1899 ifilterfalse_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1901 PyObject
*func
, *seq
;
1903 ifilterfalseobject
*lz
;
1905 if (!_PyArg_NoKeywords("ifilterfalse()", kwds
))
1908 if (!PyArg_UnpackTuple(args
, "ifilterfalse", 2, 2, &func
, &seq
))
1912 it
= PyObject_GetIter(seq
);
1916 /* create ifilterfalseobject structure */
1917 lz
= (ifilterfalseobject
*)type
->tp_alloc(type
, 0);
1926 return (PyObject
*)lz
;
1930 ifilterfalse_dealloc(ifilterfalseobject
*lz
)
1932 PyObject_GC_UnTrack(lz
);
1933 Py_XDECREF(lz
->func
);
1935 lz
->ob_type
->tp_free(lz
);
1939 ifilterfalse_traverse(ifilterfalseobject
*lz
, visitproc visit
, void *arg
)
1947 ifilterfalse_next(ifilterfalseobject
*lz
)
1950 PyObject
*it
= lz
->it
;
1952 PyObject
*(*iternext
)(PyObject
*);
1954 assert(PyIter_Check(it
));
1955 iternext
= *it
->ob_type
->tp_iternext
;
1957 item
= iternext(it
);
1961 if (lz
->func
== Py_None
) {
1962 ok
= PyObject_IsTrue(item
);
1965 good
= PyObject_CallFunctionObjArgs(lz
->func
,
1971 ok
= PyObject_IsTrue(good
);
1980 PyDoc_STRVAR(ifilterfalse_doc
,
1981 "ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1983 Return those items of sequence for which function(item) is false.\n\
1984 If function is None, return the items that are false.");
1986 static PyTypeObject ifilterfalse_type
= {
1987 PyObject_HEAD_INIT(NULL
)
1989 "itertools.ifilterfalse", /* tp_name */
1990 sizeof(ifilterfalseobject
), /* tp_basicsize */
1991 0, /* tp_itemsize */
1993 (destructor
)ifilterfalse_dealloc
, /* tp_dealloc */
1999 0, /* tp_as_number */
2000 0, /* tp_as_sequence */
2001 0, /* tp_as_mapping */
2005 PyObject_GenericGetAttr
, /* tp_getattro */
2006 0, /* tp_setattro */
2007 0, /* tp_as_buffer */
2008 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
2009 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2010 ifilterfalse_doc
, /* tp_doc */
2011 (traverseproc
)ifilterfalse_traverse
, /* tp_traverse */
2013 0, /* tp_richcompare */
2014 0, /* tp_weaklistoffset */
2015 PyObject_SelfIter
, /* tp_iter */
2016 (iternextfunc
)ifilterfalse_next
, /* tp_iternext */
2022 0, /* tp_descr_get */
2023 0, /* tp_descr_set */
2024 0, /* tp_dictoffset */
2027 ifilterfalse_new
, /* tp_new */
2028 PyObject_GC_Del
, /* tp_free */
2032 /* count object ************************************************************/
2039 static PyTypeObject count_type
;
2042 count_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
2047 if (!_PyArg_NoKeywords("count()", kwds
))
2050 if (!PyArg_ParseTuple(args
, "|n:count", &cnt
))
2053 /* create countobject structure */
2054 lz
= (countobject
*)PyObject_New(countobject
, &count_type
);
2059 return (PyObject
*)lz
;
2063 count_next(countobject
*lz
)
2065 return PyInt_FromSize_t(lz
->cnt
++);
2069 count_repr(countobject
*lz
)
2071 return PyString_FromFormat("count(%zd)", lz
->cnt
);
2074 PyDoc_STRVAR(count_doc
,
2075 "count([firstval]) --> count object\n\
2077 Return a count object whose .next() method returns consecutive\n\
2078 integers starting from zero or, if specified, from firstval.");
2080 static PyTypeObject count_type
= {
2081 PyObject_HEAD_INIT(NULL
)
2083 "itertools.count", /* tp_name */
2084 sizeof(countobject
), /* tp_basicsize */
2085 0, /* tp_itemsize */
2087 (destructor
)PyObject_Del
, /* tp_dealloc */
2092 (reprfunc
)count_repr
, /* tp_repr */
2093 0, /* tp_as_number */
2094 0, /* tp_as_sequence */
2095 0, /* tp_as_mapping */
2099 PyObject_GenericGetAttr
, /* tp_getattro */
2100 0, /* tp_setattro */
2101 0, /* tp_as_buffer */
2102 Py_TPFLAGS_DEFAULT
, /* tp_flags */
2103 count_doc
, /* tp_doc */
2104 0, /* tp_traverse */
2106 0, /* tp_richcompare */
2107 0, /* tp_weaklistoffset */
2108 PyObject_SelfIter
, /* tp_iter */
2109 (iternextfunc
)count_next
, /* tp_iternext */
2115 0, /* tp_descr_get */
2116 0, /* tp_descr_set */
2117 0, /* tp_dictoffset */
2120 count_new
, /* tp_new */
2124 /* izip object ************************************************************/
2130 Py_ssize_t tuplesize
;
2131 PyObject
*ittuple
; /* tuple of iterators */
2135 static PyTypeObject izip_type
;
2138 izip_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
2142 PyObject
*ittuple
; /* tuple of iterators */
2144 Py_ssize_t tuplesize
= PySequence_Length(args
);
2146 if (!_PyArg_NoKeywords("izip()", kwds
))
2149 /* args must be a tuple */
2150 assert(PyTuple_Check(args
));
2152 /* obtain iterators */
2153 ittuple
= PyTuple_New(tuplesize
);
2154 if (ittuple
== NULL
)
2156 for (i
=0; i
< tuplesize
; ++i
) {
2157 PyObject
*item
= PyTuple_GET_ITEM(args
, i
);
2158 PyObject
*it
= PyObject_GetIter(item
);
2160 if (PyErr_ExceptionMatches(PyExc_TypeError
))
2161 PyErr_Format(PyExc_TypeError
,
2162 "izip argument #%zd must support iteration",
2167 PyTuple_SET_ITEM(ittuple
, i
, it
);
2170 /* create a result holder */
2171 result
= PyTuple_New(tuplesize
);
2172 if (result
== NULL
) {
2176 for (i
=0 ; i
< tuplesize
; i
++) {
2178 PyTuple_SET_ITEM(result
, i
, Py_None
);
2181 /* create izipobject structure */
2182 lz
= (izipobject
*)type
->tp_alloc(type
, 0);
2188 lz
->ittuple
= ittuple
;
2189 lz
->tuplesize
= tuplesize
;
2190 lz
->result
= result
;
2192 return (PyObject
*)lz
;
2196 izip_dealloc(izipobject
*lz
)
2198 PyObject_GC_UnTrack(lz
);
2199 Py_XDECREF(lz
->ittuple
);
2200 Py_XDECREF(lz
->result
);
2201 lz
->ob_type
->tp_free(lz
);
2205 izip_traverse(izipobject
*lz
, visitproc visit
, void *arg
)
2207 Py_VISIT(lz
->ittuple
);
2208 Py_VISIT(lz
->result
);
2213 izip_next(izipobject
*lz
)
2216 Py_ssize_t tuplesize
= lz
->tuplesize
;
2217 PyObject
*result
= lz
->result
;
2224 if (result
->ob_refcnt
== 1) {
2226 for (i
=0 ; i
< tuplesize
; i
++) {
2227 it
= PyTuple_GET_ITEM(lz
->ittuple
, i
);
2228 assert(PyIter_Check(it
));
2229 item
= (*it
->ob_type
->tp_iternext
)(it
);
2234 olditem
= PyTuple_GET_ITEM(result
, i
);
2235 PyTuple_SET_ITEM(result
, i
, item
);
2239 result
= PyTuple_New(tuplesize
);
2242 for (i
=0 ; i
< tuplesize
; i
++) {
2243 it
= PyTuple_GET_ITEM(lz
->ittuple
, i
);
2244 assert(PyIter_Check(it
));
2245 item
= (*it
->ob_type
->tp_iternext
)(it
);
2250 PyTuple_SET_ITEM(result
, i
, item
);
2256 PyDoc_STRVAR(izip_doc
,
2257 "izip(iter1 [,iter2 [...]]) --> izip object\n\
2259 Return a izip object whose .next() method returns a tuple where\n\
2260 the i-th element comes from the i-th iterable argument. The .next()\n\
2261 method continues until the shortest iterable in the argument sequence\n\
2262 is exhausted and then it raises StopIteration. Works like the zip()\n\
2263 function but consumes less memory by returning an iterator instead of\n\
2266 static PyTypeObject izip_type
= {
2267 PyObject_HEAD_INIT(NULL
)
2269 "itertools.izip", /* tp_name */
2270 sizeof(izipobject
), /* tp_basicsize */
2271 0, /* tp_itemsize */
2273 (destructor
)izip_dealloc
, /* tp_dealloc */
2279 0, /* tp_as_number */
2280 0, /* tp_as_sequence */
2281 0, /* tp_as_mapping */
2285 PyObject_GenericGetAttr
, /* tp_getattro */
2286 0, /* tp_setattro */
2287 0, /* tp_as_buffer */
2288 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
2289 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2290 izip_doc
, /* tp_doc */
2291 (traverseproc
)izip_traverse
, /* tp_traverse */
2293 0, /* tp_richcompare */
2294 0, /* tp_weaklistoffset */
2295 PyObject_SelfIter
, /* tp_iter */
2296 (iternextfunc
)izip_next
, /* tp_iternext */
2302 0, /* tp_descr_get */
2303 0, /* tp_descr_set */
2304 0, /* tp_dictoffset */
2307 izip_new
, /* tp_new */
2308 PyObject_GC_Del
, /* tp_free */
2312 /* repeat object ************************************************************/
2320 static PyTypeObject repeat_type
;
2323 repeat_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
2327 Py_ssize_t cnt
= -1;
2329 if (!_PyArg_NoKeywords("repeat()", kwds
))
2332 if (!PyArg_ParseTuple(args
, "O|n:repeat", &element
, &cnt
))
2335 if (PyTuple_Size(args
) == 2 && cnt
< 0)
2338 ro
= (repeatobject
*)type
->tp_alloc(type
, 0);
2342 ro
->element
= element
;
2344 return (PyObject
*)ro
;
2348 repeat_dealloc(repeatobject
*ro
)
2350 PyObject_GC_UnTrack(ro
);
2351 Py_XDECREF(ro
->element
);
2352 ro
->ob_type
->tp_free(ro
);
2356 repeat_traverse(repeatobject
*ro
, visitproc visit
, void *arg
)
2358 Py_VISIT(ro
->element
);
2363 repeat_next(repeatobject
*ro
)
2369 Py_INCREF(ro
->element
);
2374 repeat_repr(repeatobject
*ro
)
2376 PyObject
*result
, *objrepr
;
2378 objrepr
= PyObject_Repr(ro
->element
);
2379 if (objrepr
== NULL
)
2383 result
= PyString_FromFormat("repeat(%s)",
2384 PyString_AS_STRING(objrepr
));
2386 result
= PyString_FromFormat("repeat(%s, %zd)",
2387 PyString_AS_STRING(objrepr
), ro
->cnt
);
2393 repeat_len(repeatobject
*ro
)
2395 if (ro
->cnt
== -1) {
2396 PyErr_SetString(PyExc_TypeError
, "len() of unsized object");
2399 return PyInt_FromSize_t(ro
->cnt
);
2402 PyDoc_STRVAR(length_hint_doc
, "Private method returning an estimate of len(list(it)).");
2404 static PyMethodDef repeat_methods
[] = {
2405 {"__length_hint__", (PyCFunction
)repeat_len
, METH_NOARGS
, length_hint_doc
},
2406 {NULL
, NULL
} /* sentinel */
2409 PyDoc_STRVAR(repeat_doc
,
2410 "repeat(element [,times]) -> create an iterator which returns the element\n\
2411 for the specified number of times. If not specified, returns the element\n\
2414 static PyTypeObject repeat_type
= {
2415 PyObject_HEAD_INIT(NULL
)
2417 "itertools.repeat", /* tp_name */
2418 sizeof(repeatobject
), /* tp_basicsize */
2419 0, /* tp_itemsize */
2421 (destructor
)repeat_dealloc
, /* tp_dealloc */
2426 (reprfunc
)repeat_repr
, /* tp_repr */
2427 0, /* tp_as_number */
2428 0, /* tp_as_sequence */
2429 0, /* tp_as_mapping */
2433 PyObject_GenericGetAttr
, /* tp_getattro */
2434 0, /* tp_setattro */
2435 0, /* tp_as_buffer */
2436 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
2437 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2438 repeat_doc
, /* tp_doc */
2439 (traverseproc
)repeat_traverse
, /* tp_traverse */
2441 0, /* tp_richcompare */
2442 0, /* tp_weaklistoffset */
2443 PyObject_SelfIter
, /* tp_iter */
2444 (iternextfunc
)repeat_next
, /* tp_iternext */
2445 repeat_methods
, /* tp_methods */
2450 0, /* tp_descr_get */
2451 0, /* tp_descr_set */
2452 0, /* tp_dictoffset */
2455 repeat_new
, /* tp_new */
2456 PyObject_GC_Del
, /* tp_free */
2460 /* module level code ********************************************************/
2462 PyDoc_STRVAR(module_doc
,
2463 "Functional tools for creating and using iterators.\n\
2465 Infinite iterators:\n\
2466 count([n]) --> n, n+1, n+2, ...\n\
2467 cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
2468 repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
2470 Iterators terminating on the shortest input sequence:\n\
2471 izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
2472 ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
2473 ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
2474 islice(seq, [start,] stop [, step]) --> elements from\n\
2475 seq[start:stop:step]\n\
2476 imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
2477 starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
2478 tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
2479 chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
2480 takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
2481 dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
2482 groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\
2486 static PyMethodDef module_methods
[] = {
2487 {"tee", (PyCFunction
)tee
, METH_VARARGS
, tee_doc
},
2488 {NULL
, NULL
} /* sentinel */
2497 PyTypeObject
*typelist
[] = {
2514 teedataobject_type
.ob_type
= &PyType_Type
;
2515 m
= Py_InitModule3("itertools", module_methods
, module_doc
);
2519 for (i
=0 ; typelist
[i
] != NULL
; i
++) {
2520 if (PyType_Ready(typelist
[i
]) < 0)
2522 name
= strchr(typelist
[i
]->tp_name
, '.');
2523 assert (name
!= NULL
);
2524 Py_INCREF(typelist
[i
]);
2525 PyModule_AddObject(m
, name
+1, (PyObject
*)typelist
[i
]);
2528 if (PyType_Ready(&teedataobject_type
) < 0)
2530 if (PyType_Ready(&tee_type
) < 0)
2532 if (PyType_Ready(&_grouper_type
) < 0)