Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1dfde1d

Browse files
committed
Replace map(None, *iterables) with zip(*iterables).
1 parent 86def6c commit 1dfde1d

9 files changed

Lines changed: 20 additions & 90 deletions

File tree

Doc/library/functions.rst

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -648,17 +648,7 @@ available. They are listed here in alphabetical order.
648648
Return an iterator that applies *function* to every item of *iterable*,
649649
yielding the results. If additional *iterable* arguments are passed,
650650
*function* must take that many arguments and is applied to the items from all
651-
iterables in parallel. If one iterable is shorter than another it is assumed
652-
to be extended with ``None`` items. If *function* is ``None``, the identity
653-
function is assumed; if there are multiple arguments, :func:`map` returns a
654-
list consisting of tuples containing the corresponding items from all
655-
iterables (a kind of transpose operation). The *iterable* arguments may be a
656-
sequence or any iterable object; the result is always a list.
657-
658-
Note that for only one *iterable* argument, ``map(function, iterable)`` is
659-
equivalent to the generator expression ``(function(item) for item in
660-
iterable)`` if *function* is not ``None``.
661-
651+
iterables in parallel.
662652

663653
.. function:: max(iterable[, args...], *[, key])
664654

Doc/library/itertools.rst

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,21 +204,13 @@ loops that truncate the stream.
204204
.. function:: imap(function, *iterables)
205205

206206
Make an iterator that computes the function using arguments from each of the
207-
iterables. If *function* is set to ``None``, then :func:`imap` returns the
208-
arguments as a tuple. Like :func:`map` but stops when the shortest iterable is
209-
exhausted instead of filling in ``None`` for shorter iterables. The reason for
210-
the difference is that infinite iterator arguments are typically an error for
211-
:func:`map` (because the output is fully evaluated) but represent a common and
212-
useful way of supplying arguments to :func:`imap`. Equivalent to::
207+
iterables. Equivalent to::
213208

214209
def imap(function, *iterables):
215-
iterables = map(iter, iterables)
210+
iterables = [iter(it) for it in iterables)
216211
while True:
217-
args = [next(i) for i in iterables]
218-
if function is None:
219-
yield tuple(args)
220-
else:
221-
yield function(*args)
212+
args = [next(it) for it in iterables]
213+
yield function(*args)
222214

223215

224216
.. function:: islice(iterable, [start,] stop [, step])

Lib/heapq.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,8 @@ def nsmallest(n, iterable, key=None):
351351
Equivalent to: sorted(iterable, key=key)[:n]
352352
"""
353353
in1, in2 = tee(iterable)
354-
it = izip(map(key, in1), count(), in2) # decorate
354+
keys = in1 if key is None else map(key, in1)
355+
it = izip(keys, count(), in2) # decorate
355356
result = _nsmallest(n, it)
356357
return list(map(itemgetter(2), result)) # undecorate
357358

@@ -362,7 +363,8 @@ def nlargest(n, iterable, key=None):
362363
Equivalent to: sorted(iterable, key=key, reverse=True)[:n]
363364
"""
364365
in1, in2 = tee(iterable)
365-
it = izip(map(key, in1), map(neg, count()), in2) # decorate
366+
keys = in1 if key is None else map(key, in1)
367+
it = izip(keys, map(neg, count()), in2) # decorate
366368
result = _nlargest(n, it)
367369
return list(map(itemgetter(2), result)) # undecorate
368370

Lib/test/test_builtin.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,18 +1099,6 @@ def __long__(self):
10991099
# self.assertRaises(TypeError, long, Foo5())
11001100

11011101
def test_map(self):
1102-
self.assertEqual(
1103-
list(map(None, 'hello')),
1104-
[('h',), ('e',), ('l',), ('l',), ('o',)]
1105-
)
1106-
self.assertEqual(
1107-
list(map(None, 'abcd', 'efg')),
1108-
[('a', 'e'), ('b', 'f'), ('c', 'g')]
1109-
)
1110-
self.assertEqual(
1111-
list(map(None, range(3))),
1112-
[(0,), (1,), (2,)]
1113-
)
11141102
self.assertEqual(
11151103
list(map(lambda x: x*x, range(1,4))),
11161104
[1, 4, 9]
@@ -1145,18 +1133,10 @@ def plus(*v):
11451133
list(map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0])),
11461134
[1+4+1, 3+9+1, 7+2+0]
11471135
)
1148-
self.assertEqual(
1149-
list(map(None, Squares(10))),
1150-
[(0,), (1,), (4,), (9,), (16,), (25,), (36,), (49,), (64,), (81,)]
1151-
)
11521136
self.assertEqual(
11531137
list(map(int, Squares(10))),
11541138
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
11551139
)
1156-
self.assertEqual(
1157-
list(map(None, Squares(3), Squares(2))),
1158-
[(0,0), (1,1)]
1159-
)
11601140
def Max(a, b):
11611141
if a is None:
11621142
return b
@@ -1169,7 +1149,6 @@ def Max(a, b):
11691149
)
11701150
self.assertRaises(TypeError, map)
11711151
self.assertRaises(TypeError, map, lambda x: x, 42)
1172-
self.assertEqual(list(map(None, [42])), [(42,)])
11731152
class BadSeq:
11741153
def __iter__(self):
11751154
raise ValueError

Lib/test/test_iter.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -382,25 +382,17 @@ def test_builtin_max_min(self):
382382

383383
# Test map()'s use of iterators.
384384
def test_builtin_map(self):
385-
self.assertEqual(list(map(None, SequenceClass(5))),
386-
[(0,), (1,), (2,), (3,), (4,)])
387385
self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
388386
list(range(1, 6)))
389387

390388
d = {"one": 1, "two": 2, "three": 3}
391-
self.assertEqual(list(map(None, d)), [(k,) for k in d])
392389
self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
393390
list(d.items()))
394391
dkeys = list(d.keys())
395392
expected = [(i < len(d) and dkeys[i] or None,
396393
i,
397394
i < len(d) and dkeys[i] or None)
398395
for i in range(3)]
399-
self.assertEqual(list(map(None,
400-
d,
401-
SequenceClass(5),
402-
iter(d.keys()))),
403-
expected)
404396

405397
f = open(TESTFN, "w")
406398
try:

Lib/test/test_itertools.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ def test_iziplongest(self):
236236
self.assertEqual(list(izip_longest('abcdef')), list(zip('abcdef')))
237237

238238
self.assertEqual(list(izip_longest('abc', 'defg', **{})),
239-
list(map(None, list('abc')+[None], 'defg'))) # empty keyword dict
239+
list(izip(list('abc')+[None], 'defg'))) # empty keyword dict
240240
self.assertRaises(TypeError, izip_longest, 3)
241241
self.assertRaises(TypeError, izip_longest, range(3), 3)
242242

@@ -281,14 +281,17 @@ def test_repeat(self):
281281
def test_imap(self):
282282
self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
283283
[0**1, 1**2, 2**3])
284-
self.assertEqual(list(imap(None, 'abc', range(5))),
284+
def tupleize(*args):
285+
return args
286+
self.assertEqual(list(imap(tupleize, 'abc', range(5))),
285287
[('a',0),('b',1),('c',2)])
286-
self.assertEqual(list(imap(None, 'abc', count())),
288+
self.assertEqual(list(imap(tupleize, 'abc', count())),
287289
[('a',0),('b',1),('c',2)])
288-
self.assertEqual(take(2,imap(None, 'abc', count())),
290+
self.assertEqual(take(2,imap(tupleize, 'abc', count())),
289291
[('a',0),('b',1)])
290292
self.assertEqual(list(imap(operator.pow, [])), [])
291293
self.assertRaises(TypeError, imap)
294+
self.assertRaises(TypeError, list, imap(None, range(3), range(3)))
292295
self.assertRaises(TypeError, imap, operator.neg)
293296
self.assertRaises(TypeError, next, imap(10, range(5)))
294297
self.assertRaises(ValueError, next, imap(errfunc, [4], [5]))

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.0a3?
1212
Core and Builtins
1313
-----------------
1414

15+
- map() and itertools.imap() no longer accept None for the first argument.
16+
Use zip() instead.
17+
1518
- Issue #1769: Now int("- 1") is not allowed any more.
1619

1720
- Object/longobject.c: long(float('nan')) raises an OverflowError instead

Modules/itertoolsmodule.c

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,31 +1490,6 @@ imap_traverse(imapobject *lz, visitproc visit, void *arg)
14901490
return 0;
14911491
}
14921492

1493-
/*
1494-
imap() is an iterator version of __builtins__.map() except that it does
1495-
not have the None fill-in feature. That was intentionally left out for
1496-
the following reasons:
1497-
1498-
1) Itertools are designed to be easily combined and chained together.
1499-
Having all tools stop with the shortest input is a unifying principle
1500-
that makes it easier to combine finite iterators (supplying data) with
1501-
infinite iterators like count() and repeat() (for supplying sequential
1502-
or constant arguments to a function).
1503-
1504-
2) In typical use cases for combining itertools, having one finite data
1505-
supplier run out before another is likely to be an error condition which
1506-
should not pass silently by automatically supplying None.
1507-
1508-
3) The use cases for automatic None fill-in are rare -- not many functions
1509-
do something useful when a parameter suddenly switches type and becomes
1510-
None.
1511-
1512-
4) If a need does arise, it can be met by __builtins__.map() or by
1513-
writing: chain(iterable, repeat(None)).
1514-
1515-
5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
1516-
*/
1517-
15181493
static PyObject *
15191494
imap_next(imapobject *lz)
15201495
{
@@ -1536,8 +1511,6 @@ imap_next(imapobject *lz)
15361511
}
15371512
PyTuple_SET_ITEM(argtuple, i, val);
15381513
}
1539-
if (lz->func == Py_None)
1540-
return argtuple;
15411514
result = PyObject_Call(lz->func, argtuple, NULL);
15421515
Py_DECREF(argtuple);
15431516
return result;
@@ -1547,10 +1520,7 @@ PyDoc_STRVAR(imap_doc,
15471520
"imap(func, *iterables) --> imap object\n\
15481521
\n\
15491522
Make an iterator that computes the function using arguments from\n\
1550-
each of the iterables. Like map() except that it returns\n\
1551-
an iterator instead of a list and that it stops when the shortest\n\
1552-
iterable is exhausted instead of filling in None for shorter\n\
1553-
iterables.");
1523+
each of the iterables. Stops when the shortest iterable is exhausted.");
15541524

15551525
static PyTypeObject imap_type = {
15561526
PyVarObject_HEAD_INIT(NULL, 0)

Python/bltinmodule.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,6 @@ Return an iterator yielding the results of applying the function to the\n\
815815
items of the argument iterables(s). If more than one iterable is given,\n\
816816
the function is called with an argument list consisting of the\n\
817817
corresponding item of each iterable, until an iterable is exhausted.\n\
818-
If the function is None, 'lambda *a: a' is assumed.\n\
819818
(This is identical to itertools.imap().)");
820819

821820

0 commit comments

Comments
 (0)