mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Replace map(None, *iterables) with zip(*iterables).
This commit is contained in:
parent
86def6cb2b
commit
1dfde1ddc0
9 changed files with 20 additions and 90 deletions
|
@ -648,17 +648,7 @@ available. They are listed here in alphabetical order.
|
|||
Return an iterator that applies *function* to every item of *iterable*,
|
||||
yielding the results. If additional *iterable* arguments are passed,
|
||||
*function* must take that many arguments and is applied to the items from all
|
||||
iterables in parallel. If one iterable is shorter than another it is assumed
|
||||
to be extended with ``None`` items. If *function* is ``None``, the identity
|
||||
function is assumed; if there are multiple arguments, :func:`map` returns a
|
||||
list consisting of tuples containing the corresponding items from all
|
||||
iterables (a kind of transpose operation). The *iterable* arguments may be a
|
||||
sequence or any iterable object; the result is always a list.
|
||||
|
||||
Note that for only one *iterable* argument, ``map(function, iterable)`` is
|
||||
equivalent to the generator expression ``(function(item) for item in
|
||||
iterable)`` if *function* is not ``None``.
|
||||
|
||||
iterables in parallel.
|
||||
|
||||
.. function:: max(iterable[, args...], *[, key])
|
||||
|
||||
|
|
|
@ -204,20 +204,12 @@ loops that truncate the stream.
|
|||
.. function:: imap(function, *iterables)
|
||||
|
||||
Make an iterator that computes the function using arguments from each of the
|
||||
iterables. If *function* is set to ``None``, then :func:`imap` returns the
|
||||
arguments as a tuple. Like :func:`map` but stops when the shortest iterable is
|
||||
exhausted instead of filling in ``None`` for shorter iterables. The reason for
|
||||
the difference is that infinite iterator arguments are typically an error for
|
||||
:func:`map` (because the output is fully evaluated) but represent a common and
|
||||
useful way of supplying arguments to :func:`imap`. Equivalent to::
|
||||
iterables. Equivalent to::
|
||||
|
||||
def imap(function, *iterables):
|
||||
iterables = map(iter, iterables)
|
||||
iterables = [iter(it) for it in iterables)
|
||||
while True:
|
||||
args = [next(i) for i in iterables]
|
||||
if function is None:
|
||||
yield tuple(args)
|
||||
else:
|
||||
args = [next(it) for it in iterables]
|
||||
yield function(*args)
|
||||
|
||||
|
||||
|
|
|
@ -351,7 +351,8 @@ def nsmallest(n, iterable, key=None):
|
|||
Equivalent to: sorted(iterable, key=key)[:n]
|
||||
"""
|
||||
in1, in2 = tee(iterable)
|
||||
it = izip(map(key, in1), count(), in2) # decorate
|
||||
keys = in1 if key is None else map(key, in1)
|
||||
it = izip(keys, count(), in2) # decorate
|
||||
result = _nsmallest(n, it)
|
||||
return list(map(itemgetter(2), result)) # undecorate
|
||||
|
||||
|
@ -362,7 +363,8 @@ def nlargest(n, iterable, key=None):
|
|||
Equivalent to: sorted(iterable, key=key, reverse=True)[:n]
|
||||
"""
|
||||
in1, in2 = tee(iterable)
|
||||
it = izip(map(key, in1), map(neg, count()), in2) # decorate
|
||||
keys = in1 if key is None else map(key, in1)
|
||||
it = izip(keys, map(neg, count()), in2) # decorate
|
||||
result = _nlargest(n, it)
|
||||
return list(map(itemgetter(2), result)) # undecorate
|
||||
|
||||
|
|
|
@ -1099,18 +1099,6 @@ class BuiltinTest(unittest.TestCase):
|
|||
# self.assertRaises(TypeError, long, Foo5())
|
||||
|
||||
def test_map(self):
|
||||
self.assertEqual(
|
||||
list(map(None, 'hello')),
|
||||
[('h',), ('e',), ('l',), ('l',), ('o',)]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(map(None, 'abcd', 'efg')),
|
||||
[('a', 'e'), ('b', 'f'), ('c', 'g')]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(map(None, range(3))),
|
||||
[(0,), (1,), (2,)]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(map(lambda x: x*x, range(1,4))),
|
||||
[1, 4, 9]
|
||||
|
@ -1145,18 +1133,10 @@ class BuiltinTest(unittest.TestCase):
|
|||
list(map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0])),
|
||||
[1+4+1, 3+9+1, 7+2+0]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(map(None, Squares(10))),
|
||||
[(0,), (1,), (4,), (9,), (16,), (25,), (36,), (49,), (64,), (81,)]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(map(int, Squares(10))),
|
||||
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(map(None, Squares(3), Squares(2))),
|
||||
[(0,0), (1,1)]
|
||||
)
|
||||
def Max(a, b):
|
||||
if a is None:
|
||||
return b
|
||||
|
@ -1169,7 +1149,6 @@ class BuiltinTest(unittest.TestCase):
|
|||
)
|
||||
self.assertRaises(TypeError, map)
|
||||
self.assertRaises(TypeError, map, lambda x: x, 42)
|
||||
self.assertEqual(list(map(None, [42])), [(42,)])
|
||||
class BadSeq:
|
||||
def __iter__(self):
|
||||
raise ValueError
|
||||
|
|
|
@ -382,13 +382,10 @@ class TestCase(unittest.TestCase):
|
|||
|
||||
# Test map()'s use of iterators.
|
||||
def test_builtin_map(self):
|
||||
self.assertEqual(list(map(None, SequenceClass(5))),
|
||||
[(0,), (1,), (2,), (3,), (4,)])
|
||||
self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
|
||||
list(range(1, 6)))
|
||||
|
||||
d = {"one": 1, "two": 2, "three": 3}
|
||||
self.assertEqual(list(map(None, d)), [(k,) for k in d])
|
||||
self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
|
||||
list(d.items()))
|
||||
dkeys = list(d.keys())
|
||||
|
@ -396,11 +393,6 @@ class TestCase(unittest.TestCase):
|
|||
i,
|
||||
i < len(d) and dkeys[i] or None)
|
||||
for i in range(3)]
|
||||
self.assertEqual(list(map(None,
|
||||
d,
|
||||
SequenceClass(5),
|
||||
iter(d.keys()))),
|
||||
expected)
|
||||
|
||||
f = open(TESTFN, "w")
|
||||
try:
|
||||
|
|
|
@ -236,7 +236,7 @@ class TestBasicOps(unittest.TestCase):
|
|||
self.assertEqual(list(izip_longest('abcdef')), list(zip('abcdef')))
|
||||
|
||||
self.assertEqual(list(izip_longest('abc', 'defg', **{})),
|
||||
list(map(None, list('abc')+[None], 'defg'))) # empty keyword dict
|
||||
list(izip(list('abc')+[None], 'defg'))) # empty keyword dict
|
||||
self.assertRaises(TypeError, izip_longest, 3)
|
||||
self.assertRaises(TypeError, izip_longest, range(3), 3)
|
||||
|
||||
|
@ -281,14 +281,17 @@ class TestBasicOps(unittest.TestCase):
|
|||
def test_imap(self):
|
||||
self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
|
||||
[0**1, 1**2, 2**3])
|
||||
self.assertEqual(list(imap(None, 'abc', range(5))),
|
||||
def tupleize(*args):
|
||||
return args
|
||||
self.assertEqual(list(imap(tupleize, 'abc', range(5))),
|
||||
[('a',0),('b',1),('c',2)])
|
||||
self.assertEqual(list(imap(None, 'abc', count())),
|
||||
self.assertEqual(list(imap(tupleize, 'abc', count())),
|
||||
[('a',0),('b',1),('c',2)])
|
||||
self.assertEqual(take(2,imap(None, 'abc', count())),
|
||||
self.assertEqual(take(2,imap(tupleize, 'abc', count())),
|
||||
[('a',0),('b',1)])
|
||||
self.assertEqual(list(imap(operator.pow, [])), [])
|
||||
self.assertRaises(TypeError, imap)
|
||||
self.assertRaises(TypeError, list, imap(None, range(3), range(3)))
|
||||
self.assertRaises(TypeError, imap, operator.neg)
|
||||
self.assertRaises(TypeError, next, imap(10, range(5)))
|
||||
self.assertRaises(ValueError, next, imap(errfunc, [4], [5]))
|
||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 3.0a3?
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- map() and itertools.imap() no longer accept None for the first argument.
|
||||
Use zip() instead.
|
||||
|
||||
- Issue #1769: Now int("- 1") is not allowed any more.
|
||||
|
||||
- Object/longobject.c: long(float('nan')) raises an OverflowError instead
|
||||
|
|
|
@ -1490,31 +1490,6 @@ imap_traverse(imapobject *lz, visitproc visit, void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
imap() is an iterator version of __builtins__.map() except that it does
|
||||
not have the None fill-in feature. That was intentionally left out for
|
||||
the following reasons:
|
||||
|
||||
1) Itertools are designed to be easily combined and chained together.
|
||||
Having all tools stop with the shortest input is a unifying principle
|
||||
that makes it easier to combine finite iterators (supplying data) with
|
||||
infinite iterators like count() and repeat() (for supplying sequential
|
||||
or constant arguments to a function).
|
||||
|
||||
2) In typical use cases for combining itertools, having one finite data
|
||||
supplier run out before another is likely to be an error condition which
|
||||
should not pass silently by automatically supplying None.
|
||||
|
||||
3) The use cases for automatic None fill-in are rare -- not many functions
|
||||
do something useful when a parameter suddenly switches type and becomes
|
||||
None.
|
||||
|
||||
4) If a need does arise, it can be met by __builtins__.map() or by
|
||||
writing: chain(iterable, repeat(None)).
|
||||
|
||||
5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
imap_next(imapobject *lz)
|
||||
{
|
||||
|
@ -1536,8 +1511,6 @@ imap_next(imapobject *lz)
|
|||
}
|
||||
PyTuple_SET_ITEM(argtuple, i, val);
|
||||
}
|
||||
if (lz->func == Py_None)
|
||||
return argtuple;
|
||||
result = PyObject_Call(lz->func, argtuple, NULL);
|
||||
Py_DECREF(argtuple);
|
||||
return result;
|
||||
|
@ -1547,10 +1520,7 @@ 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. Like map() except that it returns\n\
|
||||
an iterator instead of a list and that it stops when the shortest\n\
|
||||
iterable is exhausted instead of filling in None for shorter\n\
|
||||
iterables.");
|
||||
each of the iterables. Stops when the shortest iterable is exhausted.");
|
||||
|
||||
static PyTypeObject imap_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
|
|
|
@ -815,7 +815,6 @@ 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\
|
||||
If the function is None, 'lambda *a: a' is assumed.\n\
|
||||
(This is identical to itertools.imap().)");
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue