Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
61fe64d5
Kaydet (Commit)
61fe64d5
authored
Şub 23, 2003
tarafından
Raymond Hettinger
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
User requested changes to the itertools module.
Subsumed times() into repeat(). Added cycle() and chain().
üst
c85b6a2d
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
300 additions
and
101 deletions
+300
-101
libitertools.tex
Doc/lib/libitertools.tex
+50
-38
test_itertools.py
Lib/test/test_itertools.py
+12
-11
NEWS
Misc/NEWS
+3
-1
itertoolsmodule.c
Modules/itertoolsmodule.c
+235
-51
No files found.
Doc/lib/libitertools.tex
Dosyayı görüntüle @
61fe64d5
...
@@ -33,22 +33,8 @@ Adopting the principles of just-in-time manufacturing, they create
...
@@ -33,22 +33,8 @@ Adopting the principles of just-in-time manufacturing, they create
data when and where needed instead of consuming memory with the
data when and where needed instead of consuming memory with the
computer equivalent of ``inventory''.
computer equivalent of ``inventory''.
Some tools were omitted from the module because they offered no
The module author welcomes suggestions for other basic building blocks
advantage over their pure python counterparts or because their behavior
to be added to future versions of the module.
was too surprising.
For instance, SML provides a tool:
\code
{
cycle(
\var
{
seq
}
)
}
which
loops over the sequence elements and then starts again when the
sequence is exhausted. The surprising behavior is the need for
significant auxiliary storage (which is unusual for an iterator).
If needed, the tool is readily constructible using pure Python.
Other tools are being considered for inclusion in future versions of the
module. For instance, the function
\function
{
chain(
\var
{
it0
}
,
\var
{
it1
}
, ...)
}
would return elements from
the first iterator until it was exhausted and then move on to each
successive iterator. The module author welcomes suggestions for other
basic building blocks.
\begin{seealso}
\begin{seealso}
\seetext
{
The Standard ML Basis Library,
\seetext
{
The Standard ML Basis Library,
...
@@ -67,6 +53,20 @@ The following module functions all construct and return iterators.
...
@@ -67,6 +53,20 @@ The following module functions all construct and return iterators.
Some provide streams of infinite length, so they should only be accessed
Some provide streams of infinite length, so they should only be accessed
by functions or loops that truncate the stream.
by functions or loops that truncate the stream.
\begin{funcdesc}
{
chain
}{
*iterables
}
Make an iterator that returns elements from the first iterable until
it is exhausted, then proceeds to the next iterable, until all of the
iterables are exhausted. Used for treating consecutive sequences as
a single sequence. Equivalent to:
\begin{verbatim}
def chain(*iterables):
for it in iterables:
for element in it:
yield element
\end{verbatim}
\end{funcdesc}
\begin{funcdesc}
{
count
}{
\optional
{
n
}}
\begin{funcdesc}
{
count
}{
\optional
{
n
}}
Make an iterator that returns consecutive integers starting with
\var
{
n
}
.
Make an iterator that returns consecutive integers starting with
\var
{
n
}
.
Does not currently support python long integers. Often used as an
Does not currently support python long integers. Often used as an
...
@@ -85,6 +85,29 @@ by functions or loops that truncate the stream.
...
@@ -85,6 +85,29 @@ by functions or loops that truncate the stream.
may change in the future.
may change in the future.
\end{funcdesc}
\end{funcdesc}
\begin{funcdesc}
{
cycle
}{
iterable
}
Make an iterator returning elements from the iterable and saving a
copy of each. When the iterable is exhausted, return elements from
the saved copy. Repeats indefinitely. Equivalent to:
\begin{verbatim}
def cycle(iterable):
saved = []
for element in iterable:
yield element
saved.append(element)
if len(saved) == 0:
return
while True:
for element in saved:
yield element
\end{verbatim}
Note, this is the only member of the toolkit that may require
significant auxiliary storage (depending on the length of the
iterable.
\end{funcdesc}
\begin{funcdesc}
{
dropwhile
}{
predicate, iterable
}
\begin{funcdesc}
{
dropwhile
}{
predicate, iterable
}
Make an iterator that drops elements from the iterable as long as
Make an iterator that drops elements from the iterable as long as
the predicate is true; afterwards, returns every element. Note,
the predicate is true; afterwards, returns every element. Note,
...
@@ -207,16 +230,21 @@ by functions or loops that truncate the stream.
...
@@ -207,16 +230,21 @@ by functions or loops that truncate the stream.
\end{verbatim}
\end{verbatim}
\end{funcdesc}
\end{funcdesc}
\begin{funcdesc}
{
repeat
}{
object
}
\begin{funcdesc}
{
repeat
}{
object
\optional
{
, times
}
}
Make an iterator that returns
\var
{
object
}
over and over again.
Make an iterator that returns
\var
{
object
}
over and over again.
Runs indefinitely unless the
\var
{
times
}
argument is specified.
Used as argument to
\function
{
imap()
}
for invariant parameters
Used as argument to
\function
{
imap()
}
for invariant parameters
to the called function. Also used with
\function
{
izip()
}
to create
to the called function. Also used with
\function
{
izip()
}
to create
an invariant part of a tuple record. Equivalent to:
an invariant part of a tuple record. Equivalent to:
\begin{verbatim}
\begin{verbatim}
def repeat(object):
def repeat(object, times=None):
if times is None:
while True:
while True:
yield object
yield object
else:
for i in xrange(times):
yield object
\end{verbatim}
\end{verbatim}
\end{funcdesc}
\end{funcdesc}
...
@@ -253,20 +281,6 @@ by functions or loops that truncate the stream.
...
@@ -253,20 +281,6 @@ by functions or loops that truncate the stream.
\end{verbatim}
\end{verbatim}
\end{funcdesc}
\end{funcdesc}
\begin{funcdesc}
{
times
}{
n,
\optional
{
object
}}
Make an iterator that returns
\var
{
object
}
\var
{
n
}
times.
\var
{
object
}
defaults to
\code
{
None
}
. Used for looping a specific
number of times without creating a number object on each pass.
Equivalent to:
\begin{verbatim}
def times(n, object=None):
if n<0 : raise ValueError
for i in xrange(n):
yield object
\end{verbatim}
\end{funcdesc}
\subsection
{
Examples
\label
{
itertools-example
}}
\subsection
{
Examples
\label
{
itertools-example
}}
...
@@ -274,12 +288,6 @@ The following examples show common uses for each tool and
...
@@ -274,12 +288,6 @@ The following examples show common uses for each tool and
demonstrate ways they can be combined.
demonstrate ways they can be combined.
\begin{verbatim}
\begin{verbatim}
>>> for i in times(3):
... print "Hello"
...
Hello
Hello
Hello
>>> amounts = [120.15, 764.05, 823.14]
>>> amounts = [120.15, 764.05, 823.14]
>>> for checknum, amount in izip(count(1200), amounts):
>>> for checknum, amount in izip(count(1200), amounts):
...
@@ -343,4 +351,8 @@ from building blocks.
...
@@ -343,4 +351,8 @@ from building blocks.
... "Returns True if pred
(
x
)
is False for every element in the iterable"
... "Returns True if pred
(
x
)
is False for every element in the iterable"
... return not nth
(
ifilter
(
pred, seq
)
,
0
)
... return not nth
(
ifilter
(
pred, seq
)
,
0
)
>>> def pairwise
(
seq
)
:
... "s
-
>
(
s
0
,s
1
)
,
(
s
1
,s
2
)
,
(
s
2
, s
3
)
, ..."
... return izip
(
seq, islice
(
seq,
1
,len
(
seq
)))
\end
{
verbatim
}
\end
{
verbatim
}
Lib/test/test_itertools.py
Dosyayı görüntüle @
61fe64d5
...
@@ -4,11 +4,18 @@ from itertools import *
...
@@ -4,11 +4,18 @@ from itertools import *
import
sys
import
sys
class
TestBasicOps
(
unittest
.
TestCase
):
class
TestBasicOps
(
unittest
.
TestCase
):
def
test_chain
(
self
):
self
.
assertEqual
(
list
(
chain
(
'abc'
,
'def'
)),
list
(
'abcdef'
))
def
test_count
(
self
):
def
test_count
(
self
):
self
.
assertEqual
(
zip
(
'abc'
,
count
()),
[(
'a'
,
0
),
(
'b'
,
1
),
(
'c'
,
2
)])
self
.
assertEqual
(
zip
(
'abc'
,
count
()),
[(
'a'
,
0
),
(
'b'
,
1
),
(
'c'
,
2
)])
self
.
assertEqual
(
zip
(
'abc'
,
count
(
3
)),
[(
'a'
,
3
),
(
'b'
,
4
),
(
'c'
,
5
)])
self
.
assertEqual
(
zip
(
'abc'
,
count
(
3
)),
[(
'a'
,
3
),
(
'b'
,
4
),
(
'c'
,
5
)])
self
.
assertRaises
(
TypeError
,
count
,
2
,
3
)
self
.
assertRaises
(
TypeError
,
count
,
2
,
3
)
def
test_cycle
(
self
):
self
.
assertEqual
(
list
(
islice
(
cycle
(
'abc'
),
10
)),
list
(
'abcabcabca'
))
self
.
assertEqual
(
list
(
cycle
(
''
)),
[])
def
test_ifilter
(
self
):
def
test_ifilter
(
self
):
def
isEven
(
x
):
def
isEven
(
x
):
return
x
%
2
==
0
return
x
%
2
==
0
...
@@ -35,13 +42,9 @@ class TestBasicOps(unittest.TestCase):
...
@@ -35,13 +42,9 @@ class TestBasicOps(unittest.TestCase):
def
test_repeat
(
self
):
def
test_repeat
(
self
):
self
.
assertEqual
(
zip
(
xrange
(
3
),
repeat
(
'a'
)),
self
.
assertEqual
(
zip
(
xrange
(
3
),
repeat
(
'a'
)),
[(
0
,
'a'
),
(
1
,
'a'
),
(
2
,
'a'
)])
[(
0
,
'a'
),
(
1
,
'a'
),
(
2
,
'a'
)])
self
.
assertEqual
(
list
(
repeat
(
'a'
,
3
)),
[
'a'
,
'a'
,
'a'
])
self
.
assertRaises
(
TypeError
,
repeat
)
self
.
assertRaises
(
TypeError
,
repeat
)
def
test_times
(
self
):
self
.
assertEqual
(
list
(
times
(
3
)),
[
None
]
*
3
)
self
.
assertEqual
(
list
(
times
(
3
,
True
)),
[
True
]
*
3
)
self
.
assertRaises
(
ValueError
,
times
,
-
1
)
def
test_imap
(
self
):
def
test_imap
(
self
):
import
operator
import
operator
self
.
assertEqual
(
list
(
imap
(
operator
.
pow
,
range
(
3
),
range
(
1
,
7
))),
self
.
assertEqual
(
list
(
imap
(
operator
.
pow
,
range
(
3
),
range
(
1
,
7
))),
...
@@ -94,12 +97,6 @@ class TestBasicOps(unittest.TestCase):
...
@@ -94,12 +97,6 @@ class TestBasicOps(unittest.TestCase):
libreftest
=
""" Doctest for examples in the library reference, libitertools.tex
libreftest
=
""" Doctest for examples in the library reference, libitertools.tex
>>> for i in times(3):
... print "Hello"
...
Hello
Hello
Hello
>>> amounts = [120.15, 764.05, 823.14]
>>> amounts = [120.15, 764.05, 823.14]
>>> for checknum, amount in izip(count(1200), amounts):
>>> for checknum, amount in izip(count(1200), amounts):
...
@@ -154,6 +151,10 @@ Samuele
...
@@ -154,6 +151,10 @@ Samuele
... "Returns True if pred(x) is False for every element in the iterable"
... "Returns True if pred(x) is False for every element in the iterable"
... return not nth(ifilter(pred, seq), 0)
... return not nth(ifilter(pred, seq), 0)
>>> def pairwise(seq):
... "s -> (s0,s1), (s1,s2), (s2, s3), ..."
... return izip(seq, islice(seq,1,len(seq)))
"""
"""
__test__
=
{
'libreftest'
:
libreftest
}
__test__
=
{
'libreftest'
:
libreftest
}
...
...
Misc/NEWS
Dosyayı görüntüle @
61fe64d5
...
@@ -17,7 +17,9 @@ TBD
...
@@ -17,7 +17,9 @@ TBD
Extension modules
Extension modules
-----------------
-----------------
TBD
- Made user requested changes to the itertools module.
Subsumed the times() function into repeat().
Added chain() and cycle().
Library
Library
-------
-------
...
...
Modules/itertoolsmodule.c
Dosyayı görüntüle @
61fe64d5
...
@@ -7,6 +7,163 @@
...
@@ -7,6 +7,163 @@
All rights reserved.
All rights reserved.
*/
*/
/* cycle object **********************************************************/
typedef
struct
{
PyObject_HEAD
PyObject
*
it
;
PyObject
*
saved
;
int
firstpass
;
}
cycleobject
;
PyTypeObject
cycle_type
;
static
PyObject
*
cycle_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
{
PyObject
*
it
;
PyObject
*
iterable
;
PyObject
*
saved
;
cycleobject
*
lz
;
if
(
!
PyArg_UnpackTuple
(
args
,
"cycle"
,
1
,
1
,
&
iterable
))
return
NULL
;
/* Get iterator. */
it
=
PyObject_GetIter
(
iterable
);
if
(
it
==
NULL
)
return
NULL
;
saved
=
PyList_New
(
0
);
if
(
saved
==
NULL
)
{
Py_DECREF
(
it
);
return
NULL
;
}
/* create cycleobject structure */
lz
=
(
cycleobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
{
Py_DECREF
(
it
);
Py_DECREF
(
saved
);
return
NULL
;
}
lz
->
it
=
it
;
lz
->
saved
=
saved
;
lz
->
firstpass
=
0
;
return
(
PyObject
*
)
lz
;
}
static
void
cycle_dealloc
(
cycleobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
saved
);
Py_XDECREF
(
lz
->
it
);
lz
->
ob_type
->
tp_free
(
lz
);
}
static
int
cycle_traverse
(
cycleobject
*
lz
,
visitproc
visit
,
void
*
arg
)
{
int
err
;
if
(
lz
->
it
)
{
err
=
visit
(
lz
->
it
,
arg
);
if
(
err
)
return
err
;
}
if
(
lz
->
saved
)
{
err
=
visit
(
lz
->
saved
,
arg
);
if
(
err
)
return
err
;
}
return
0
;
}
static
PyObject
*
cycle_next
(
cycleobject
*
lz
)
{
PyObject
*
item
;
PyObject
*
it
;
while
(
1
)
{
item
=
PyIter_Next
(
lz
->
it
);
if
(
item
!=
NULL
)
{
if
(
!
lz
->
firstpass
)
PyList_Append
(
lz
->
saved
,
item
);
return
item
;
}
if
(
PyList_Size
(
lz
->
saved
)
==
0
)
return
NULL
;
it
=
PyObject_GetIter
(
lz
->
saved
);
if
(
it
==
NULL
)
return
NULL
;
Py_DECREF
(
lz
->
it
);
lz
->
it
=
it
;
lz
->
firstpass
=
1
;
}
}
static
PyObject
*
cycle_getiter
(
PyObject
*
lz
)
{
Py_INCREF
(
lz
);
return
lz
;
}
PyDoc_STRVAR
(
cycle_doc
,
"cycle(iterable) --> cycle object
\n
\
\n
\
Return elements from the iterable until it is exhausted.
\n
\
Then repeat the sequence indefinitely."
);
PyTypeObject
cycle_type
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
"itertools.cycle"
,
/* tp_name */
sizeof
(
cycleobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
cycle_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_str */
PyObject_GenericGetAttr
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
|
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
cycle_doc
,
/* tp_doc */
(
traverseproc
)
cycle_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
(
getiterfunc
)
cycle_getiter
,
/* tp_iter */
(
iternextfunc
)
cycle_next
,
/* tp_iternext */
0
,
/* tp_methods */
0
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_dict */
0
,
/* tp_descr_get */
0
,
/* tp_descr_set */
0
,
/* tp_dictoffset */
0
,
/* tp_init */
PyType_GenericAlloc
,
/* tp_alloc */
cycle_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
};
/* dropwhile object **********************************************************/
/* dropwhile object **********************************************************/
typedef
struct
{
typedef
struct
{
...
@@ -826,93 +983,110 @@ PyTypeObject imap_type = {
...
@@ -826,93 +983,110 @@ PyTypeObject imap_type = {
};
};
/*
times
object ************************************************************/
/*
chain
object ************************************************************/
typedef
struct
{
typedef
struct
{
PyObject_HEAD
PyObject_HEAD
PyObject
*
obj
;
long
tuplesize
;
long
cnt
;
long
iternum
;
/* which iterator is active */
}
timesobject
;
PyObject
*
ittuple
;
/* tuple of iterators */
}
chainobject
;
PyTypeObject
times
_type
;
PyTypeObject
chain
_type
;
static
PyObject
*
static
PyObject
*
times
_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
chain
_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
{
{
timesobject
*
lz
;
chainobject
*
lz
;
PyObject
*
obj
=
Py_None
;
int
tuplesize
=
PySequence_Length
(
args
);
long
cnt
;
int
i
;
PyObject
*
ittuple
;
if
(
!
PyArg_ParseTuple
(
args
,
"l|O:times"
,
&
cnt
,
&
obj
))
/* obtain iterators */
assert
(
PyTuple_Check
(
args
));
ittuple
=
PyTuple_New
(
tuplesize
);
if
(
ittuple
==
NULL
)
return
NULL
;
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
++
i
)
{
if
(
cnt
<
0
)
{
PyObject
*
item
=
PyTuple_GET_ITEM
(
args
,
i
);
PyErr_SetString
(
PyExc_ValueError
,
PyObject
*
it
=
PyObject_GetIter
(
item
);
"count for times() cannot be negative."
);
if
(
it
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"chain argument #%d must support iteration"
,
i
+
1
);
Py_DECREF
(
ittuple
);
return
NULL
;
return
NULL
;
}
}
PyTuple_SET_ITEM
(
ittuple
,
i
,
it
);
}
/* create
times
object structure */
/* create
chain
object structure */
lz
=
(
times
object
*
)
type
->
tp_alloc
(
type
,
0
);
lz
=
(
chain
object
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
if
(
lz
==
NULL
)
return
NULL
;
return
NULL
;
lz
->
cnt
=
cnt
;
Py_INCREF
(
obj
);
lz
->
ittuple
=
ittuple
;
lz
->
obj
=
obj
;
lz
->
iternum
=
0
;
lz
->
tuplesize
=
tuplesize
;
return
(
PyObject
*
)
lz
;
return
(
PyObject
*
)
lz
;
}
}
static
void
static
void
times_dealloc
(
times
object
*
lz
)
chain_dealloc
(
chain
object
*
lz
)
{
{
PyObject_GC_UnTrack
(
lz
);
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
obj
);
Py_XDECREF
(
lz
->
ittuple
);
lz
->
ob_type
->
tp_free
(
lz
);
lz
->
ob_type
->
tp_free
(
lz
);
}
}
static
int
static
int
times_traverse
(
times
object
*
lz
,
visitproc
visit
,
void
*
arg
)
chain_traverse
(
chain
object
*
lz
,
visitproc
visit
,
void
*
arg
)
{
{
if
(
lz
->
obj
)
if
(
lz
->
ittuple
)
return
visit
(
lz
->
obj
,
arg
);
return
visit
(
lz
->
ittuple
,
arg
);
return
0
;
return
0
;
}
}
static
PyObject
*
static
PyObject
*
times_next
(
times
object
*
lz
)
chain_next
(
chain
object
*
lz
)
{
{
PyObject
*
obj
=
lz
->
obj
;
PyObject
*
it
;
PyObject
*
item
;
if
(
lz
->
cnt
>
0
)
{
while
(
lz
->
iternum
<
lz
->
tuplesize
)
{
lz
->
cnt
--
;
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
lz
->
iternum
);
Py_INCREF
(
obj
);
item
=
PyIter_Next
(
it
);
return
obj
;
if
(
item
!=
NULL
)
return
item
;
lz
->
iternum
++
;
}
}
return
NULL
;
return
NULL
;
}
}
static
PyObject
*
static
PyObject
*
times
_getiter
(
PyObject
*
lz
)
chain
_getiter
(
PyObject
*
lz
)
{
{
Py_INCREF
(
lz
);
Py_INCREF
(
lz
);
return
lz
;
return
lz
;
}
}
PyDoc_STRVAR
(
times
_doc
,
PyDoc_STRVAR
(
chain
_doc
,
"
times(n [,obj]) --> times
object
\n
\
"
chain(*iterables) --> chain
object
\n
\
\n
\
\n
\
Return a times object whose .next() method returns n consecutive
\n
\
Return a chain object whose .next() method returns elements from the
\n
\
instances of obj (default is None)."
);
first iterable until it is exhausted, then elements from the next
\n
\
iterable, until all of the iterables are exhausted."
);
PyTypeObject
times
_type
=
{
PyTypeObject
chain
_type
=
{
PyObject_HEAD_INIT
(
NULL
)
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
0
,
/* ob_size */
"itertools.
times
"
,
/* tp_name */
"itertools.
chain
"
,
/* tp_name */
sizeof
(
times
object
),
/* tp_basicsize */
sizeof
(
chain
object
),
/* tp_basicsize */
0
,
/* tp_itemsize */
0
,
/* tp_itemsize */
/* methods */
/* methods */
(
destructor
)
times
_dealloc
,
/* tp_dealloc */
(
destructor
)
chain
_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_setattr */
...
@@ -929,13 +1103,13 @@ PyTypeObject times_type = {
...
@@ -929,13 +1103,13 @@ PyTypeObject times_type = {
0
,
/* tp_as_buffer */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
|
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
|
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
times
_doc
,
/* tp_doc */
chain
_doc
,
/* tp_doc */
(
traverseproc
)
times
_traverse
,
/* tp_traverse */
(
traverseproc
)
chain
_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
0
,
/* tp_weaklistoffset */
(
getiterfunc
)
times
_getiter
,
/* tp_iter */
(
getiterfunc
)
chain
_getiter
,
/* tp_iter */
(
iternextfunc
)
times
_next
,
/* tp_iternext */
(
iternextfunc
)
chain
_next
,
/* tp_iternext */
0
,
/* tp_methods */
0
,
/* tp_methods */
0
,
/* tp_members */
0
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_getset */
...
@@ -946,7 +1120,7 @@ PyTypeObject times_type = {
...
@@ -946,7 +1120,7 @@ PyTypeObject times_type = {
0
,
/* tp_dictoffset */
0
,
/* tp_dictoffset */
0
,
/* tp_init */
0
,
/* tp_init */
PyType_GenericAlloc
,
/* tp_alloc */
PyType_GenericAlloc
,
/* tp_alloc */
times
_new
,
/* tp_new */
chain
_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
PyObject_GC_Del
,
/* tp_free */
};
};
...
@@ -1544,6 +1718,7 @@ PyTypeObject izip_type = {
...
@@ -1544,6 +1718,7 @@ PyTypeObject izip_type = {
typedef
struct
{
typedef
struct
{
PyObject_HEAD
PyObject_HEAD
PyObject
*
element
;
PyObject
*
element
;
long
cnt
;
}
repeatobject
;
}
repeatobject
;
PyTypeObject
repeat_type
;
PyTypeObject
repeat_type
;
...
@@ -1553,8 +1728,9 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -1553,8 +1728,9 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
repeatobject
*
ro
;
repeatobject
*
ro
;
PyObject
*
element
;
PyObject
*
element
;
long
cnt
=
-
1
;
if
(
!
PyArg_
UnpackTuple
(
args
,
"repeat"
,
1
,
1
,
&
eleme
nt
))
if
(
!
PyArg_
ParseTuple
(
args
,
"O|l:repeat"
,
&
element
,
&
c
nt
))
return
NULL
;
return
NULL
;
ro
=
(
repeatobject
*
)
type
->
tp_alloc
(
type
,
0
);
ro
=
(
repeatobject
*
)
type
->
tp_alloc
(
type
,
0
);
...
@@ -1562,6 +1738,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -1562,6 +1738,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return
NULL
;
return
NULL
;
Py_INCREF
(
element
);
Py_INCREF
(
element
);
ro
->
element
=
element
;
ro
->
element
=
element
;
ro
->
cnt
=
cnt
;
return
(
PyObject
*
)
ro
;
return
(
PyObject
*
)
ro
;
}
}
...
@@ -1584,6 +1761,10 @@ repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
...
@@ -1584,6 +1761,10 @@ repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
static
PyObject
*
static
PyObject
*
repeat_next
(
repeatobject
*
ro
)
repeat_next
(
repeatobject
*
ro
)
{
{
if
(
ro
->
cnt
==
0
)
return
NULL
;
if
(
ro
->
cnt
>
0
)
ro
->
cnt
--
;
Py_INCREF
(
ro
->
element
);
Py_INCREF
(
ro
->
element
);
return
ro
->
element
;
return
ro
->
element
;
}
}
...
@@ -1596,7 +1777,9 @@ repeat_getiter(PyObject *ro)
...
@@ -1596,7 +1777,9 @@ repeat_getiter(PyObject *ro)
}
}
PyDoc_STRVAR
(
repeat_doc
,
PyDoc_STRVAR
(
repeat_doc
,
"repeat(element) -> create an iterator which returns the element endlessly."
);
"repeat(element [,times]) -> create an iterator which returns the element
\n
\
for the specified number of times. If not specified, returns the element
\n
\
endlessly."
);
PyTypeObject
repeat_type
=
{
PyTypeObject
repeat_type
=
{
PyObject_HEAD_INIT
(
NULL
)
PyObject_HEAD_INIT
(
NULL
)
...
@@ -1651,7 +1834,8 @@ PyDoc_STRVAR(module_doc,
...
@@ -1651,7 +1834,8 @@ PyDoc_STRVAR(module_doc,
\n
\
\n
\
Infinite iterators:
\n
\
Infinite iterators:
\n
\
count([n]) --> n, n+1, n+2, ...
\n
\
count([n]) --> n, n+1, n+2, ...
\n
\
repeat(elem) --> elem, elem, elem, ...
\n
\
cycle(p) --> p0, p1, ... plast, p0, p1, ...
\n
\
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or upto n times
\n
\
\n
\
\n
\
Iterators terminating on the shortest input sequence:
\n
\
Iterators terminating on the shortest input sequence:
\n
\
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...
\n
\
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...
\n
\
...
@@ -1661,7 +1845,7 @@ islice(seq, [start,] stop [, step]) --> elements from\n\
...
@@ -1661,7 +1845,7 @@ islice(seq, [start,] stop [, step]) --> elements from\n\
seq[start:stop:step]
\n
\
seq[start:stop:step]
\n
\
imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...
\n
\
imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...
\n
\
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
\n
\
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
\n
\
times(n, [obj]) --> obj, obj, ... for n times. obj defaults to None
\n
\
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...
\n
\
takewhile(pred, seq) --> seq[0], seq[1], until pred fails
\n
\
takewhile(pred, seq) --> seq[0], seq[1], until pred fails
\n
\
dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails
\n
\
dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails
\n
\
"
);
"
);
...
@@ -1674,12 +1858,13 @@ inititertools(void)
...
@@ -1674,12 +1858,13 @@ inititertools(void)
PyObject
*
m
;
PyObject
*
m
;
char
*
name
;
char
*
name
;
PyTypeObject
*
typelist
[]
=
{
PyTypeObject
*
typelist
[]
=
{
&
cycle_type
,
&
dropwhile_type
,
&
dropwhile_type
,
&
takewhile_type
,
&
takewhile_type
,
&
islice_type
,
&
islice_type
,
&
starmap_type
,
&
starmap_type
,
&
imap_type
,
&
imap_type
,
&
times
_type
,
&
chain
_type
,
&
ifilter_type
,
&
ifilter_type
,
&
ifilterfalse_type
,
&
ifilterfalse_type
,
&
count_type
,
&
count_type
,
...
@@ -1694,8 +1879,7 @@ inititertools(void)
...
@@ -1694,8 +1879,7 @@ inititertools(void)
if
(
PyType_Ready
(
typelist
[
i
])
<
0
)
if
(
PyType_Ready
(
typelist
[
i
])
<
0
)
return
;
return
;
name
=
strchr
(
typelist
[
i
]
->
tp_name
,
'.'
)
+
1
;
name
=
strchr
(
typelist
[
i
]
->
tp_name
,
'.'
)
+
1
;
if
(
name
==
NULL
)
assert
(
name
!=
NULL
);
return
;
Py_INCREF
(
typelist
[
i
]);
Py_INCREF
(
typelist
[
i
]);
PyModule_AddObject
(
m
,
name
,
(
PyObject
*
)
typelist
[
i
]);
PyModule_AddObject
(
m
,
name
,
(
PyObject
*
)
typelist
[
i
]);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment