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
4c350ca0
Commit
4c350ca0
authored
Mar 13, 2008
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issues 2186 and 2187. Move map() from itertools to builtins.
parent
a88d4c7b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
158 additions
and
203 deletions
+158
-203
Doc/library/itertools.rst
Doc/library/itertools.rst
+10
-27
Lib/filecmp.py
Lib/filecmp.py
+3
-3
Lib/test/seq_tests.py
Lib/test/seq_tests.py
+2
-2
Lib/test/test_heapq.py
Lib/test/test_heapq.py
+2
-2
Lib/test/test_itertools.py
Lib/test/test_itertools.py
+1
-0
Lib/test/test_set.py
Lib/test/test_set.py
+2
-2
Modules/itertoolsmodule.c
Modules/itertoolsmodule.c
+0
-151
Python/bltinmodule.c
Python/bltinmodule.c
+138
-16
No files found.
Doc/library/itertools.rst
View file @
4c350ca0
...
...
@@ -22,9 +22,8 @@ The tools are designed to combine readily with one another. This makes it easy
to construct more specialized tools succinctly and efficiently in pure Python.
For instance, SML provides a tabulation tool: ``tabulate(f)`` which produces a
sequence ``f(0), f(1), ...``. This toolbox provides :func:`imap` and
:func:`count` which can be combined to form ``imap(f, count())`` and produce an
equivalent result.
sequence ``f(0), f(1), ...``. But, this effect can be achieved in Python
by combining :func:`map` and :func:`count` to form ``map(f, count())``.
Likewise, the functional tools are designed to work well with the high-speed
functions provided by the :mod:`operator` module.
...
...
@@ -138,7 +137,7 @@ loops that truncate the stream.
.. function:: count([n])
Make an iterator that returns consecutive integers starting with *n*. If not
specified *n* defaults to zero. Often used as an argument to :func:`
i
map` to
specified *n* defaults to zero. Often used as an argument to :func:`map` to
generate consecutive data points. Also, used with :func:`izip` to add sequence
numbers. Equivalent to::
...
...
@@ -248,22 +247,6 @@ loops that truncate the stream.
yield x
.. function:: imap(function, *iterables)
Make an iterator that computes the function using arguments from each of the
iterables. This function is the same as the built-in :func:`map` function.
Equivalent to::
def imap(function, *iterables):
iterables = [iter(it) for it in iterables)
while True:
args = [next(it) for it in iterables]
if function is None:
yield tuple(args)
else:
yield function(*args)
.. function:: islice(iterable, [start,] stop [, step])
Make an iterator that returns selected elements from the iterable. If *start* is
...
...
@@ -421,7 +404,7 @@ loops that truncate the stream.
.. function:: repeat(object[, times])
Make an iterator that returns *object* over and over again. Runs indefinitely
unless the *times* argument is specified. Used as argument to :func:`
i
map` for
unless the *times* argument is specified. Used as argument to :func:`map` for
invariant parameters to the called function. Also used with :func:`izip` to
create an invariant part of a tuple record. Equivalent to::
...
...
@@ -437,9 +420,9 @@ loops that truncate the stream.
.. function:: starmap(function, iterable)
Make an iterator that computes the function using arguments obtained from
the iterable. Used instead of :func:`
i
map` when argument parameters are already
the iterable. Used instead of :func:`map` when argument parameters are already
grouped in tuples from a single iterable (the data has been "pre-zipped"). The
difference between :func:`
i
map` and :func:`starmap` parallels the distinction
difference between :func:`map` and :func:`starmap` parallels the distinction
between ``function(a,b)`` and ``function(*c)``. Equivalent to::
def starmap(function, iterable):
...
...
@@ -507,7 +490,7 @@ can be combined. ::
Check 1202 is for $823.14
>>> import operator
>>> for cube in
i
map(operator.pow, range(1,5), repeat(3)):
>>> for cube in map(operator.pow, range(1,5), repeat(3)):
... print(cube)
...
1
...
...
@@ -577,7 +560,7 @@ which incur interpreter overhead. ::
def tabulate(function):
"Return function(0), function(1), ..."
return
i
map(function, count())
return map(function, count())
def nth(iterable, n):
"Returns the nth item or raise StopIteration"
...
...
@@ -603,7 +586,7 @@ which incur interpreter overhead. ::
def quantify(seq, pred=None):
"Count how many times the predicate is true in the sequence"
return sum(
i
map(pred, seq))
return sum(map(pred, seq))
def padnone(seq):
"""Returns the sequence elements and then returns None indefinitely.
...
...
@@ -617,7 +600,7 @@ which incur interpreter overhead. ::
return chain.from_iterable(repeat(seq, n))
def dotproduct(vec1, vec2):
return sum(
i
map(operator.mul, vec1, vec2))
return sum(map(operator.mul, vec1, vec2))
def flatten(listOfLists):
return list(chain.from_iterable(listOfLists))
...
...
Lib/filecmp.py
View file @
4c350ca0
...
...
@@ -12,7 +12,7 @@ Functions:
import
os
import
stat
import
warnings
from
itertools
import
ifilterfalse
,
i
map
,
i
zip
from
itertools
import
ifilterfalse
,
izip
__all__
=
[
"cmp"
,
"dircmp"
,
"cmpfiles"
]
...
...
@@ -130,8 +130,8 @@ class dircmp:
self
.
right_list
.
sort
()
def
phase1
(
self
):
# Compute common names
a
=
dict
(
izip
(
i
map
(
os
.
path
.
normcase
,
self
.
left_list
),
self
.
left_list
))
b
=
dict
(
izip
(
i
map
(
os
.
path
.
normcase
,
self
.
right_list
),
self
.
right_list
))
a
=
dict
(
izip
(
map
(
os
.
path
.
normcase
,
self
.
left_list
),
self
.
left_list
))
b
=
dict
(
izip
(
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__
,
ifilterfalse
(
b
.
__contains__
,
a
)))
self
.
right_only
=
list
(
map
(
b
.
__getitem__
,
ifilterfalse
(
a
.
__contains__
,
b
)))
...
...
Lib/test/seq_tests.py
View file @
4c350ca0
...
...
@@ -79,10 +79,10 @@ class IterFuncStop:
def
__next__
(
self
):
raise
StopIteration
from
itertools
import
chain
,
i
map
from
itertools
import
chain
,
map
def
itermulti
(
seqn
):
'Test multiple tiers of iterators'
return
chain
(
i
map
(
lambda
x
:
x
,
iterfunc
(
IterGen
(
Sequence
(
seqn
)))))
return
chain
(
map
(
lambda
x
:
x
,
iterfunc
(
IterGen
(
Sequence
(
seqn
)))))
class
CommonTest
(
unittest
.
TestCase
):
# The type to be tested
...
...
Lib/test/test_heapq.py
View file @
4c350ca0
...
...
@@ -260,10 +260,10 @@ class S:
def
__next__
(
self
):
raise
StopIteration
from
itertools
import
chain
,
i
map
from
itertools
import
chain
,
map
def
L
(
seqn
):
'Test multiple tiers of iterators'
return
chain
(
i
map
(
lambda
x
:
x
,
R
(
Ig
(
G
(
seqn
)))))
return
chain
(
map
(
lambda
x
:
x
,
R
(
Ig
(
G
(
seqn
)))))
class
TestErrorHandling
(
unittest
.
TestCase
):
# only for C implementation
...
...
Lib/test/test_itertools.py
View file @
4c350ca0
...
...
@@ -9,6 +9,7 @@ from functools import reduce
maxsize
=
test_support
.
MAX_Py_ssize_t
minsize
=
-
maxsize
-
1
ifilter
=
filter
imap
=
map
def
lzip
(
*
args
):
return
list
(
zip
(
*
args
))
...
...
Lib/test/test_set.py
View file @
4c350ca0
...
...
@@ -1560,10 +1560,10 @@ class S:
def
__next__
(
self
):
raise
StopIteration
from
itertools
import
chain
,
imap
from
itertools
import
chain
def
L
(
seqn
):
'Test multiple tiers of iterators'
return
chain
(
i
map
(
lambda
x
:
x
,
R
(
Ig
(
G
(
seqn
)))))
return
chain
(
map
(
lambda
x
:
x
,
R
(
Ig
(
G
(
seqn
)))))
class
TestVariousIteratorArgs
(
unittest
.
TestCase
):
...
...
Modules/itertoolsmodule.c
View file @
4c350ca0
...
...
@@ -1418,155 +1418,6 @@ static PyTypeObject starmap_type = {
};
/* imap object ************************************************************/
typedef
struct
{
PyObject_HEAD
PyObject
*
iters
;
PyObject
*
func
;
}
imapobject
;
static
PyTypeObject
imap_type
;
static
PyObject
*
imap_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwds
)
{
PyObject
*
it
,
*
iters
,
*
func
;
imapobject
*
lz
;
Py_ssize_t
numargs
,
i
;
if
(
type
==
&
imap_type
&&
!
_PyArg_NoKeywords
(
"imap()"
,
kwds
))
return
NULL
;
numargs
=
PyTuple_Size
(
args
);
if
(
numargs
<
2
)
{
PyErr_SetString
(
PyExc_TypeError
,
"imap() must have at least two arguments."
);
return
NULL
;
}
iters
=
PyTuple_New
(
numargs
-
1
);
if
(
iters
==
NULL
)
return
NULL
;
for
(
i
=
1
;
i
<
numargs
;
i
++
)
{
/* Get iterator. */
it
=
PyObject_GetIter
(
PyTuple_GET_ITEM
(
args
,
i
));
if
(
it
==
NULL
)
{
Py_DECREF
(
iters
);
return
NULL
;
}
PyTuple_SET_ITEM
(
iters
,
i
-
1
,
it
);
}
/* create imapobject structure */
lz
=
(
imapobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
{
Py_DECREF
(
iters
);
return
NULL
;
}
lz
->
iters
=
iters
;
func
=
PyTuple_GET_ITEM
(
args
,
0
);
Py_INCREF
(
func
);
lz
->
func
=
func
;
return
(
PyObject
*
)
lz
;
}
static
void
imap_dealloc
(
imapobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
iters
);
Py_XDECREF
(
lz
->
func
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
}
static
int
imap_traverse
(
imapobject
*
lz
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
lz
->
iters
);
Py_VISIT
(
lz
->
func
);
return
0
;
}
static
PyObject
*
imap_next
(
imapobject
*
lz
)
{
PyObject
*
val
;
PyObject
*
argtuple
;
PyObject
*
result
;
Py_ssize_t
numargs
,
i
;
numargs
=
PyTuple_Size
(
lz
->
iters
);
argtuple
=
PyTuple_New
(
numargs
);
if
(
argtuple
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
numargs
;
i
++
)
{
val
=
PyIter_Next
(
PyTuple_GET_ITEM
(
lz
->
iters
,
i
));
if
(
val
==
NULL
)
{
Py_DECREF
(
argtuple
);
return
NULL
;
}
PyTuple_SET_ITEM
(
argtuple
,
i
,
val
);
}
result
=
PyObject_Call
(
lz
->
func
,
argtuple
,
NULL
);
Py_DECREF
(
argtuple
);
return
result
;
}
PyDoc_STRVAR
(
imap_doc
,
"imap(func, *iterables) --> imap object
\n
\
\n
\
Make an iterator that computes the function using arguments from
\n
\
each of the iterables. Stops when the shortest iterable is exhausted."
);
static
PyTypeObject
imap_type
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"itertools.imap"
,
/* tp_name */
sizeof
(
imapobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
imap_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 */
imap_doc
,
/* tp_doc */
(
traverseproc
)
imap_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
PyObject_SelfIter
,
/* tp_iter */
(
iternextfunc
)
imap_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 */
imap_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
};
/* chain object ************************************************************/
typedef
struct
{
...
...
@@ -3068,7 +2919,6 @@ izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False
\n
\
islice(seq, [start,] stop [, step]) --> elements from
\n
\
seq[start:stop:step]
\n
\
imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...
\n
\
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
\n
\
tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n
\n
\
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...
\n
\
...
...
@@ -3096,7 +2946,6 @@ inititertools(void)
&
takewhile_type
,
&
islice_type
,
&
starmap_type
,
&
imap_type
,
&
chain_type
,
&
ifilterfalse_type
,
&
count_type
,
...
...
Python/bltinmodule.c
View file @
4c350ca0
...
...
@@ -864,31 +864,153 @@ Return the identity of an object. This is guaranteed to be unique among\n\
simultaneously existing objects. (Hint: it's the object's memory address.)"
);
/* map object ************************************************************/
typedef
struct
{
PyObject_HEAD
PyObject
*
iters
;
PyObject
*
func
;
}
mapobject
;
PyTypeObject
PyMap_Type
;
static
PyObject
*
builtin_map
(
PyObject
*
self
,
PyObject
*
arg
s
)
map_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwd
s
)
{
PyObject
*
itertools
,
*
imap
,
*
result
;
itertools
=
PyImport_ImportModuleNoBlock
(
"itertools"
);
if
(
itertools
==
NULL
)
PyObject
*
it
,
*
iters
,
*
func
;
mapobject
*
lz
;
Py_ssize_t
numargs
,
i
;
if
(
type
==
&
PyMap_Type
&&
!
_PyArg_NoKeywords
(
"map()"
,
kwds
))
return
NULL
;
imap
=
PyObject_GetAttrString
(
itertools
,
"imap"
);
Py_DECREF
(
itertools
);
if
(
imap
==
NULL
)
numargs
=
PyTuple_Size
(
args
);
if
(
numargs
<
2
)
{
PyErr_SetString
(
PyExc_TypeError
,
"map() must have at least two arguments."
);
return
NULL
;
}
iters
=
PyTuple_New
(
numargs
-
1
);
if
(
iters
==
NULL
)
return
NULL
;
for
(
i
=
1
;
i
<
numargs
;
i
++
)
{
/* Get iterator. */
it
=
PyObject_GetIter
(
PyTuple_GET_ITEM
(
args
,
i
));
if
(
it
==
NULL
)
{
Py_DECREF
(
iters
);
return
NULL
;
}
PyTuple_SET_ITEM
(
iters
,
i
-
1
,
it
);
}
/* create mapobject structure */
lz
=
(
mapobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
lz
==
NULL
)
{
Py_DECREF
(
iters
);
return
NULL
;
}
lz
->
iters
=
iters
;
func
=
PyTuple_GET_ITEM
(
args
,
0
);
Py_INCREF
(
func
);
lz
->
func
=
func
;
return
(
PyObject
*
)
lz
;
}
static
void
map_dealloc
(
mapobject
*
lz
)
{
PyObject_GC_UnTrack
(
lz
);
Py_XDECREF
(
lz
->
iters
);
Py_XDECREF
(
lz
->
func
);
Py_TYPE
(
lz
)
->
tp_free
(
lz
);
}
static
int
map_traverse
(
mapobject
*
lz
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
lz
->
iters
);
Py_VISIT
(
lz
->
func
);
return
0
;
}
static
PyObject
*
map_next
(
mapobject
*
lz
)
{
PyObject
*
val
;
PyObject
*
argtuple
;
PyObject
*
result
;
Py_ssize_t
numargs
,
i
;
numargs
=
PyTuple_Size
(
lz
->
iters
);
argtuple
=
PyTuple_New
(
numargs
);
if
(
argtuple
==
NULL
)
return
NULL
;
result
=
PyObject_Call
(
imap
,
args
,
NULL
);
Py_DECREF
(
imap
);
for
(
i
=
0
;
i
<
numargs
;
i
++
)
{
val
=
PyIter_Next
(
PyTuple_GET_ITEM
(
lz
->
iters
,
i
));
if
(
val
==
NULL
)
{
Py_DECREF
(
argtuple
);
return
NULL
;
}
PyTuple_SET_ITEM
(
argtuple
,
i
,
val
);
}
result
=
PyObject_Call
(
lz
->
func
,
argtuple
,
NULL
);
Py_DECREF
(
argtuple
);
return
result
;
}
PyDoc_STRVAR
(
map_doc
,
"map(func
tion, iterable[, iterable, ...]) -> iterator
\n
\
"map(func
, *iterables) --> map object
\n
\
\n
\
Return an iterator yielding the results of applying the function to the
\n
\
items of the argument iterables(s). If more than one iterable is given,
\n
\
the function is called with an argument list consisting of the
\n
\
corresponding item of each iterable, until an iterable is exhausted.
\n
\
(This is identical to itertools.imap().)"
);
Make an iterator that computes the function using arguments from
\n
\
each of the iterables. Stops when the shortest iterable is exhausted."
);
PyTypeObject
PyMap_Type
=
{
PyVarObject_HEAD_INIT
(
&
PyType_Type
,
0
)
"map"
,
/* tp_name */
sizeof
(
mapobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
map_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 */
map_doc
,
/* tp_doc */
(
traverseproc
)
map_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
PyObject_SelfIter
,
/* tp_iter */
(
iternextfunc
)
map_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 */
map_new
,
/* tp_new */
PyObject_GC_Del
,
/* tp_free */
};
static
PyObject
*
builtin_next
(
PyObject
*
self
,
PyObject
*
args
)
...
...
@@ -1893,7 +2015,6 @@ static PyMethodDef builtin_methods[] = {
{
"iter"
,
builtin_iter
,
METH_VARARGS
,
iter_doc
},
{
"len"
,
builtin_len
,
METH_O
,
len_doc
},
{
"locals"
,
(
PyCFunction
)
builtin_locals
,
METH_NOARGS
,
locals_doc
},
{
"map"
,
builtin_map
,
METH_VARARGS
,
map_doc
},
{
"max"
,
(
PyCFunction
)
builtin_max
,
METH_VARARGS
|
METH_KEYWORDS
,
max_doc
},
{
"min"
,
(
PyCFunction
)
builtin_min
,
METH_VARARGS
|
METH_KEYWORDS
,
min_doc
},
{
"next"
,
(
PyCFunction
)
builtin_next
,
METH_VARARGS
,
next_doc
},
...
...
@@ -1965,6 +2086,7 @@ _PyBuiltin_Init(void)
SETBUILTIN
(
"property"
,
&
PyProperty_Type
);
SETBUILTIN
(
"int"
,
&
PyLong_Type
);
SETBUILTIN
(
"list"
,
&
PyList_Type
);
SETBUILTIN
(
"map"
,
&
PyMap_Type
);
SETBUILTIN
(
"object"
,
&
PyBaseObject_Type
);
SETBUILTIN
(
"range"
,
&
PyRange_Type
);
SETBUILTIN
(
"reversed"
,
&
PyReversed_Type
);
...
...
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