Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
736c0ab4
Commit
736c0ab4
authored
Mar 13, 2008
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move itertools izip() code to builtins as zip(). Complete the renaming.
parent
c5a2eb94
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
281 additions
and
476 deletions
+281
-476
Include/iterobject.h
Include/iterobject.h
+0
-3
Lib/filecmp.py
Lib/filecmp.py
+3
-3
Lib/heapq.py
Lib/heapq.py
+3
-3
Lib/test/seq_tests.py
Lib/test/seq_tests.py
+1
-1
Lib/test/test_ast.py
Lib/test/test_ast.py
+2
-2
Lib/test/test_heapq.py
Lib/test/test_heapq.py
+1
-1
Lib/test/test_itertools.py
Lib/test/test_itertools.py
+81
-83
Misc/NEWS
Misc/NEWS
+5
-1
Modules/itertoolsmodule.c
Modules/itertoolsmodule.c
+12
-201
Objects/iterobject.c
Objects/iterobject.c
+0
-169
Python/bltinmodule.c
Python/bltinmodule.c
+173
-9
No files found.
Include/iterobject.h
View file @
736c0ab4
...
...
@@ -7,7 +7,6 @@ extern "C" {
PyAPI_DATA
(
PyTypeObject
)
PySeqIter_Type
;
PyAPI_DATA
(
PyTypeObject
)
PyCallIter_Type
;
PyAPI_DATA
(
PyTypeObject
)
PyZipIter_Type
;
PyAPI_DATA
(
PyTypeObject
)
PyCmpWrapper_Type
;
#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_Type)
...
...
@@ -19,8 +18,6 @@ PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *);
PyAPI_FUNC
(
PyObject
*
)
PyCallIter_New
(
PyObject
*
,
PyObject
*
);
PyObject
*
_PyZip_CreateIter
(
PyObject
*
args
);
#ifdef __cplusplus
}
#endif
...
...
Lib/filecmp.py
View file @
736c0ab4
...
...
@@ -12,7 +12,7 @@ Functions:
import
os
import
stat
import
warnings
from
itertools
import
filterfalse
,
izip
from
itertools
import
filterfalse
__all__
=
[
"cmp"
,
"dircmp"
,
"cmpfiles"
]
...
...
@@ -130,8 +130,8 @@ class dircmp:
self
.
right_list
.
sort
()
def
phase1
(
self
):
# Compute common names
a
=
dict
(
i
zip
(
map
(
os
.
path
.
normcase
,
self
.
left_list
),
self
.
left_list
))
b
=
dict
(
i
zip
(
map
(
os
.
path
.
normcase
,
self
.
right_list
),
self
.
right_list
))
a
=
dict
(
zip
(
map
(
os
.
path
.
normcase
,
self
.
left_list
),
self
.
left_list
))
b
=
dict
(
zip
(
map
(
os
.
path
.
normcase
,
self
.
right_list
),
self
.
right_list
))
self
.
common
=
list
(
map
(
a
.
__getitem__
,
filter
(
b
.
__contains__
,
a
)))
self
.
left_only
=
list
(
map
(
a
.
__getitem__
,
filterfalse
(
b
.
__contains__
,
a
)))
self
.
right_only
=
list
(
map
(
b
.
__getitem__
,
filterfalse
(
a
.
__contains__
,
b
)))
...
...
Lib/heapq.py
View file @
736c0ab4
...
...
@@ -129,7 +129,7 @@ From all times, sorting has always been a Great Art! :-)
__all__
=
[
'heappush'
,
'heappop'
,
'heapify'
,
'heapreplace'
,
'merge'
,
'nlargest'
,
'nsmallest'
]
from
itertools
import
islice
,
repeat
,
count
,
izip
,
tee
from
itertools
import
islice
,
repeat
,
count
,
tee
from
operator
import
itemgetter
,
neg
import
bisect
...
...
@@ -352,7 +352,7 @@ def nsmallest(n, iterable, key=None):
"""
in1
,
in2
=
tee
(
iterable
)
keys
=
in1
if
key
is
None
else
map
(
key
,
in1
)
it
=
i
zip
(
keys
,
count
(),
in2
)
# decorate
it
=
zip
(
keys
,
count
(),
in2
)
# decorate
result
=
_nsmallest
(
n
,
it
)
return
list
(
map
(
itemgetter
(
2
),
result
))
# undecorate
...
...
@@ -364,7 +364,7 @@ def nlargest(n, iterable, key=None):
"""
in1
,
in2
=
tee
(
iterable
)
keys
=
in1
if
key
is
None
else
map
(
key
,
in1
)
it
=
i
zip
(
keys
,
map
(
neg
,
count
()),
in2
)
# decorate
it
=
zip
(
keys
,
map
(
neg
,
count
()),
in2
)
# decorate
result
=
_nlargest
(
n
,
it
)
return
list
(
map
(
itemgetter
(
2
),
result
))
# undecorate
...
...
Lib/test/seq_tests.py
View file @
736c0ab4
...
...
@@ -79,7 +79,7 @@ class IterFuncStop:
def
__next__
(
self
):
raise
StopIteration
from
itertools
import
chain
,
map
from
itertools
import
chain
def
itermulti
(
seqn
):
'Test multiple tiers of iterators'
return
chain
(
map
(
lambda
x
:
x
,
iterfunc
(
IterGen
(
Sequence
(
seqn
)))))
...
...
Lib/test/test_ast.py
View file @
736c0ab4
import
sys
,
itertools
import
sys
import
_ast
def
to_tuple
(
t
):
...
...
@@ -142,7 +142,7 @@ def run_tests():
for
input
,
output
,
kind
in
((
exec_tests
,
exec_results
,
"exec"
),
(
single_tests
,
single_results
,
"single"
),
(
eval_tests
,
eval_results
,
"eval"
)):
for
i
,
o
in
itertools
.
i
zip
(
input
,
output
):
for
i
,
o
in
zip
(
input
,
output
):
ast_tree
=
compile
(
i
,
"?"
,
kind
,
0x400
)
tup
=
to_tuple
(
ast_tree
)
assert
tup
==
o
,
(
"kind=%r
\
n
input=%r
\
n
expected=%r
\
n
got=%r"
%
...
...
Lib/test/test_heapq.py
View file @
736c0ab4
...
...
@@ -260,7 +260,7 @@ class S:
def
__next__
(
self
):
raise
StopIteration
from
itertools
import
chain
,
map
from
itertools
import
chain
def
L
(
seqn
):
'Test multiple tiers of iterators'
return
chain
(
map
(
lambda
x
:
x
,
R
(
Ig
(
G
(
seqn
)))))
...
...
Lib/test/test_itertools.py
View file @
736c0ab4
This diff is collapsed.
Click to expand it.
Misc/NEWS
View file @
736c0ab4
...
...
@@ -72,7 +72,7 @@ Core and Builtins
- Issue #1969: split and rsplit in bytearray are inconsistent
- map() and
itertools.imap() no longer accept
None for the first argument.
- map() and
no longer accepts
None for the first argument.
Use zip() instead.
- Issue #1769: Now int("- 1") is not allowed any more.
...
...
@@ -123,6 +123,10 @@ Core and Builtins
Extension Modules
-----------------
- Code for itertools ifilter(), imap(), and izip() moved to bultins and
renamed to filter(), map(), and zip(). Also, renamed izip_longest()
to zip_longest() and ifilterfalse() to filterfalse().
- Issue #1762972: Readded the reload() function as imp.reload()
- Bug #2111: mmap segfaults when trying to write a block opened with PROT_READ
...
...
Modules/itertoolsmodule.c
View file @
736c0ab4
...
...
@@ -2352,193 +2352,6 @@ static PyTypeObject count_type = {
};
/* izip object ************************************************************/
#include "Python.h"
typedef
struct
{
PyObject_HEAD
Py_ssize_t
tuplesize
;
PyObject
*
ittuple
;
/* tuple of iterators */
PyObject
*
result
;
}
izipobject
;
static
PyTypeObject
izip_type
;
static
PyObject
*
izip_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
{
izipobject
*
lz
;
Py_ssize_t
i
;
PyObject
*
ittuple
;
/* tuple of iterators */
PyObject
*
result
;
Py_ssize_t
tuplesize
=
PySequence_Length
(
args
);
if
(
type
==
&
izip_type
&&
!
_PyArg_NoKeywords
(
"izip()"
,
kwds
))
return
NULL
;
/* args must be a tuple */
assert
(
PyTuple_Check
(
args
));
/* obtain iterators */
ittuple
=
PyTuple_New
(
tuplesize
);
if
(
ittuple
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
++
i
)
{
PyObject
*
item
=
PyTuple_GET_ITEM
(
args
,
i
);
PyObject
*
it
=
PyObject_GetIter
(
item
);
if
(
it
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"izip argument #%zd must support iteration"
,
i
+
1
);
Py_DECREF
(
ittuple
);
return
NULL
;
}
PyTuple_SET_ITEM
(
ittuple
,
i
,
it
);
}
/* create a result holder */
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
{
Py_DECREF
(
ittuple
);
return
NULL
;
}
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
Py_INCREF
(
Py_None
);
PyTuple_SET_ITEM
(
result
,
i
,
Py_None
);
}
/* create izipobject structure */
lz
=
(
izipobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
{
Py_DECREF
(
ittuple
);
Py_DECREF
(
result
);
return
NULL
;
}
lz
->
ittuple
=
ittuple
;
lz
->
tuplesize
=
tuplesize
;
lz
->
result
=
result
;
return
(
PyObject
*
)
lz
;
}
static
void
izip_dealloc
(
izipobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
ittuple
);
Py_XDECREF
(
lz
->
result
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
}
static
int
izip_traverse
(
izipobject
*
lz
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
lz
->
ittuple
);
Py_VISIT
(
lz
->
result
);
return
0
;
}
static
PyObject
*
izip_next
(
izipobject
*
lz
)
{
Py_ssize_t
i
;
Py_ssize_t
tuplesize
=
lz
->
tuplesize
;
PyObject
*
result
=
lz
->
result
;
PyObject
*
it
;
PyObject
*
item
;
PyObject
*
olditem
;
if
(
tuplesize
==
0
)
return
NULL
;
if
(
Py_REFCNT
(
result
)
==
1
)
{
Py_INCREF
(
result
);
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
i
);
assert
(
PyIter_Check
(
it
));
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
olditem
=
PyTuple_GET_ITEM
(
result
,
i
);
PyTuple_SET_ITEM
(
result
,
i
,
item
);
Py_DECREF
(
olditem
);
}
}
else
{
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
i
);
assert
(
PyIter_Check
(
it
));
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
PyTuple_SET_ITEM
(
result
,
i
,
item
);
}
}
return
result
;
}
PyDoc_STRVAR
(
izip_doc
,
"izip(iter1 [,iter2 [...]]) --> izip object
\n
\
\n
\
Return a izip object whose .__next__() method returns a tuple where
\n
\
the i-th element comes from the i-th iterable argument. The .__next__()
\n
\
method continues until the shortest iterable in the argument sequence
\n
\
is exhausted and then it raises StopIteration. Works like the zip()
\n
\
function but consumes less memory by returning an iterator instead of
\n
\
a list."
);
static
PyTypeObject
izip_type
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"itertools.izip"
,
/* tp_name */
sizeof
(
izipobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
izip_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 */
izip_doc
,
/* tp_doc */
(
traverseproc
)
izip_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
PyObject_SelfIter
,
/* tp_iter */
(
iternextfunc
)
izip_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 */
0
,
/* tp_alloc */
izip_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
};
/* repeat object ************************************************************/
typedef
struct
{
...
...
@@ -2675,7 +2488,7 @@ static PyTypeObject repeat_type = {
PyObject_GC_Del
,
/* tp_free */
};
/*
i
ziplongest object ************************************************************/
/* ziplongest object ************************************************************/
#include "Python.h"
...
...
@@ -2686,14 +2499,14 @@ typedef struct {
PyObject
*
ittuple
;
/* tuple of iterators */
PyObject
*
result
;
PyObject
*
fillvalue
;
}
i
ziplongestobject
;
}
ziplongestobject
;
static
PyTypeObject
i
ziplongest_type
;
static
PyTypeObject
ziplongest_type
;
static
PyObject
*
zip_longest_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
{
i
ziplongestobject
*
lz
;
ziplongestobject
*
lz
;
Py_ssize_t
i
;
PyObject
*
ittuple
;
/* tuple of iterators */
PyObject
*
result
;
...
...
@@ -2741,8 +2554,8 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyTuple_SET_ITEM
(
result
,
i
,
Py_None
);
}
/* create
i
ziplongestobject structure */
lz
=
(
i
ziplongestobject
*
)
type
->
tp_alloc
(
type
,
0
);
/* create ziplongestobject structure */
lz
=
(
ziplongestobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
{
Py_DECREF
(
ittuple
);
Py_DECREF
(
result
);
...
...
@@ -2758,7 +2571,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
static
void
zip_longest_dealloc
(
i
ziplongestobject
*
lz
)
zip_longest_dealloc
(
ziplongestobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
ittuple
);
...
...
@@ -2768,7 +2581,7 @@ zip_longest_dealloc(iziplongestobject *lz)
}
static
int
zip_longest_traverse
(
i
ziplongestobject
*
lz
,
visitproc
visit
,
void
*
arg
)
zip_longest_traverse
(
ziplongestobject
*
lz
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
lz
->
ittuple
);
Py_VISIT
(
lz
->
result
);
...
...
@@ -2777,7 +2590,7 @@ zip_longest_traverse(iziplongestobject *lz, visitproc visit, void *arg)
}
static
PyObject
*
zip_longest_next
(
i
ziplongestobject
*
lz
)
zip_longest_next
(
ziplongestobject
*
lz
)
{
Py_ssize_t
i
;
Py_ssize_t
tuplesize
=
lz
->
tuplesize
;
...
...
@@ -2859,10 +2672,10 @@ are exhausted, the fillvalue is substituted in their place. The fillvalue\n\
defaults to None or can be specified by a keyword argument.
\n
\
"
);
static
PyTypeObject
i
ziplongest_type
=
{
static
PyTypeObject
ziplongest_type
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"itertools.zip_longest"
,
/* tp_name */
sizeof
(
i
ziplongestobject
),
/* tp_basicsize */
sizeof
(
ziplongestobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
zip_longest_dealloc
,
/* tp_dealloc */
...
...
@@ -2914,7 +2727,6 @@ cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times
\n
\
\n
\
Iterators terminating on the shortest input sequence:
\n
\
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...
\n
\
zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...
\n
\
filterfalse(pred, seq) --> elements of seq where pred(elem) is False
\n
\
islice(seq, [start,] stop [, step]) --> elements from
\n
\
...
...
@@ -2949,8 +2761,7 @@ inititertools(void)
&
chain_type
,
&
filterfalse_type
,
&
count_type
,
&
izip_type
,
&
iziplongest_type
,
&
ziplongest_type
,
&
product_type
,
&
repeat_type
,
&
groupby_type
,
...
...
Objects/iterobject.c
View file @
736c0ab4
...
...
@@ -230,172 +230,3 @@ PyTypeObject PyCallIter_Type = {
};
/*********************** Zip Iterator **************************/
/* Largely copied from itertools.c by Brian Holmes */
typedef
struct
zipiterobject_t
{
PyObject_HEAD
PyTupleObject
*
it_tuple
;
/* Set to NULL when iterator is exhausted */
Py_ssize_t
resultsize
;
PyTupleObject
*
result
;
/* Reusable tuple for optimization */
}
zipiterobject
;
/* Forward */
PyObject
*
_PyZip_CreateIter
(
PyObject
*
args
)
{
Py_ssize_t
i
;
Py_ssize_t
tuplesize
;
PyObject
*
ziptuple
;
PyObject
*
result
;
struct
zipiterobject_t
*
zipiter
;
assert
(
PyTuple_Check
(
args
));
if
(
Py_TYPE
(
&
PyZipIter_Type
)
==
NULL
)
{
if
(
PyType_Ready
(
&
PyZipIter_Type
)
<
0
)
return
NULL
;
}
tuplesize
=
PySequence_Length
((
PyObject
*
)
args
);
ziptuple
=
PyTuple_New
(
tuplesize
);
if
(
ziptuple
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
PyObject
*
o
=
PyTuple_GET_ITEM
(
args
,
i
);
PyObject
*
it
=
PyObject_GetIter
(
o
);
if
(
it
==
NULL
)
{
/* XXX Should we do this?
if (PyErr_ExceptionMatches(PyExc_TypeError))
PyErr_Format(PyExc_TypeError,
"zip argument #%zd must support iteration",
I+1);
*/
Py_DECREF
(
ziptuple
);
return
NULL
;
}
PyTuple_SET_ITEM
(
ziptuple
,
i
,
it
);
}
/* create a reusable result holder */
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
{
Py_DECREF
(
ziptuple
);
return
NULL
;
}
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
Py_INCREF
(
Py_None
);
PyTuple_SET_ITEM
(
result
,
i
,
Py_None
);
}
zipiter
=
PyObject_GC_New
(
zipiterobject
,
&
PyZipIter_Type
);
if
(
zipiter
==
NULL
)
{
Py_DECREF
(
ziptuple
);
Py_DECREF
(
result
);
return
NULL
;
}
zipiter
->
result
=
(
PyTupleObject
*
)
result
;
zipiter
->
resultsize
=
tuplesize
;
zipiter
->
it_tuple
=
(
PyTupleObject
*
)
ziptuple
;
_PyObject_GC_TRACK
(
zipiter
);
return
(
PyObject
*
)
zipiter
;
}
static
void
zipiter_dealloc
(
zipiterobject
*
it
)
{
_PyObject_GC_UNTRACK
(
it
);
Py_XDECREF
(
it
->
it_tuple
);
Py_XDECREF
(
it
->
result
);
PyObject_GC_Del
(
it
);
}
static
int
zipiter_traverse
(
zipiterobject
*
it
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
it
->
it_tuple
);
Py_VISIT
(
it
->
result
);
return
0
;
}
static
PyObject
*
zipiter_next
(
zipiterobject
*
zit
)
{
Py_ssize_t
i
;
Py_ssize_t
tuplesize
=
zit
->
resultsize
;
PyObject
*
result
=
(
PyObject
*
)
zit
->
result
;
PyObject
*
olditem
;
if
(
tuplesize
==
0
)
return
NULL
;
if
(
result
->
ob_refcnt
==
1
)
{
Py_INCREF
(
result
);
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
PyObject
*
it
=
PyTuple_GET_ITEM
(
zit
->
it_tuple
,
i
);
PyObject
*
item
;
assert
(
PyIter_Check
(
it
));
item
=
(
*
it
->
ob_type
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
olditem
=
PyTuple_GET_ITEM
(
result
,
i
);
PyTuple_SET_ITEM
(
result
,
i
,
item
);
Py_DECREF
(
olditem
);
}
}
else
{
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
PyObject
*
it
=
PyTuple_GET_ITEM
(
zit
->
it_tuple
,
i
);
PyObject
*
item
;
assert
(
PyIter_Check
(
it
));
item
=
(
*
it
->
ob_type
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
PyTuple_SET_ITEM
(
result
,
i
,
item
);
}
}
return
result
;
}
PyTypeObject
PyZipIter_Type
=
{
PyVarObject_HEAD_INIT
(
0
,
0
)
"zip_iterator"
,
/* tp_name */
sizeof
(
zipiterobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
zipiter_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
,
/* tp_flags */
0
,
/* tp_doc */
(
traverseproc
)
zipiter_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weakzipoffset */
PyObject_SelfIter
,
/* tp_iter */
(
iternextfunc
)
zipiter_next
,
/* tp_iternext */
0
,
/* tp_methods */
0
,
/* tp_members */
};
Python/bltinmodule.c
View file @
736c0ab4
...
...
@@ -1967,23 +1967,187 @@ When using a tuple as the second argument issubclass(X, (A, B, ...)),\n\
is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.)."
);
static
PyObject
*
builtin_zip
(
PyObject
*
self
,
PyObject
*
args
)
typedef
struct
{
PyObject_HEAD
Py_ssize_t
tuplesize
;
PyObject
*
ittuple
;
/* tuple of iterators */
PyObject
*
result
;
}
zipobject
;
PyTypeObject
PyZip_Type
;
static
PyObject
*
zip_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
{
zipobject
*
lz
;
Py_ssize_t
i
;
PyObject
*
ittuple
;
/* tuple of iterators */
PyObject
*
result
;
Py_ssize_t
tuplesize
=
PySequence_Length
(
args
);
if
(
type
==
&
PyZip_Type
&&
!
_PyArg_NoKeywords
(
"zip()"
,
kwds
))
return
NULL
;
/* args must be a tuple */
assert
(
PyTuple_Check
(
args
));
return
_PyZip_CreateIter
(
args
);
/* obtain iterators */
ittuple
=
PyTuple_New
(
tuplesize
);
if
(
ittuple
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
++
i
)
{
PyObject
*
item
=
PyTuple_GET_ITEM
(
args
,
i
);
PyObject
*
it
=
PyObject_GetIter
(
item
);
if
(
it
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"zip argument #%zd must support iteration"
,
i
+
1
);
Py_DECREF
(
ittuple
);
return
NULL
;
}
PyTuple_SET_ITEM
(
ittuple
,
i
,
it
);
}
/* create a result holder */
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
{
Py_DECREF
(
ittuple
);
return
NULL
;
}
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
Py_INCREF
(
Py_None
);
PyTuple_SET_ITEM
(
result
,
i
,
Py_None
);
}
/* create zipobject structure */
lz
=
(
zipobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
{
Py_DECREF
(
ittuple
);
Py_DECREF
(
result
);
return
NULL
;
}
lz
->
ittuple
=
ittuple
;
lz
->
tuplesize
=
tuplesize
;
lz
->
result
=
result
;
return
(
PyObject
*
)
lz
;
}
static
void
zip_dealloc
(
zipobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
ittuple
);
Py_XDECREF
(
lz
->
result
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
}
static
int
zip_traverse
(
zipobject
*
lz
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
lz
->
ittuple
);
Py_VISIT
(
lz
->
result
);
return
0
;
}
static
PyObject
*
zip_next
(
zipobject
*
lz
)
{
Py_ssize_t
i
;
Py_ssize_t
tuplesize
=
lz
->
tuplesize
;
PyObject
*
result
=
lz
->
result
;
PyObject
*
it
;
PyObject
*
item
;
PyObject
*
olditem
;
if
(
tuplesize
==
0
)
return
NULL
;
if
(
Py_REFCNT
(
result
)
==
1
)
{
Py_INCREF
(
result
);
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
i
);
assert
(
PyIter_Check
(
it
));
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
olditem
=
PyTuple_GET_ITEM
(
result
,
i
);
PyTuple_SET_ITEM
(
result
,
i
,
item
);
Py_DECREF
(
olditem
);
}
}
else
{
result
=
PyTuple_New
(
tuplesize
);
if
(
result
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
tuplesize
;
i
++
)
{
it
=
PyTuple_GET_ITEM
(
lz
->
ittuple
,
i
);
assert
(
PyIter_Check
(
it
));
item
=
(
*
Py_TYPE
(
it
)
->
tp_iternext
)(
it
);
if
(
item
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
PyTuple_SET_ITEM
(
result
,
i
,
item
);
}
}
return
result
;
}
PyDoc_STRVAR
(
zip_doc
,
"zip(it
1 [, it2 [...]]) -> iter([(it1[0], it2[0] ...), ...])
\n
\
"zip(it
er1 [,iter2 [...]]) --> zip object
\n
\
\n
\
Return an iterator yielding tuples, where each tuple contains the
\n
\
corresponding element from each of the argument iterables.
\n
\
The returned iterator ends when the shortest argument iterable is exhausted.
\n
\
(This is identical to itertools.izip().)"
);
Return a zip object whose .__next__() method returns a tuple where
\n
\
the i-th element comes from the i-th iterable argument. The .__next__()
\n
\
method continues until the shortest iterable in the argument sequence
\n
\
is exhausted and then it raises StopIteration. Works like the zip()
\n
\
function but consumes less memory by returning an iterator instead of
\n
\
a list."
);
PyTypeObject
PyZip_Type
=
{
PyVarObject_HEAD_INIT
(
&
PyType_Type
,
0
)
"zip"
,
/* tp_name */
sizeof
(
zipobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
zip_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 */
zip_doc
,
/* tp_doc */
(
traverseproc
)
zip_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
PyObject_SelfIter
,
/* tp_iter */
(
iternextfunc
)
zip_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 */
zip_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
};
static
PyMethodDef
builtin_methods
[]
=
{
...
...
@@ -2028,7 +2192,6 @@ static PyMethodDef builtin_methods[] = {
{
"sorted"
,
(
PyCFunction
)
builtin_sorted
,
METH_VARARGS
|
METH_KEYWORDS
,
sorted_doc
},
{
"sum"
,
builtin_sum
,
METH_VARARGS
,
sum_doc
},
{
"vars"
,
builtin_vars
,
METH_VARARGS
,
vars_doc
},
{
"zip"
,
builtin_zip
,
METH_VARARGS
,
zip_doc
},
{
NULL
,
NULL
},
};
...
...
@@ -2097,6 +2260,7 @@ _PyBuiltin_Init(void)
SETBUILTIN
(
"super"
,
&
PySuper_Type
);
SETBUILTIN
(
"tuple"
,
&
PyTuple_Type
);
SETBUILTIN
(
"type"
,
&
PyType_Type
);
SETBUILTIN
(
"zip"
,
&
PyZip_Type
);
debug
=
PyBool_FromLong
(
Py_OptimizeFlag
==
0
);
if
(
PyDict_SetItemString
(
dict
,
"__debug__"
,
debug
)
<
0
)
{
Py_XDECREF
(
debug
);
...
...
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