Commit b5a42088 authored by Raymond Hettinger's avatar Raymond Hettinger

Modified itertools.izip() to match the behavior of __builtin__.zip()

which can now take zero arguments.
parent 77fe69bd
...@@ -226,10 +226,13 @@ by functions or loops that truncate the stream. ...@@ -226,10 +226,13 @@ by functions or loops that truncate the stream.
\begin{verbatim} \begin{verbatim}
def izip(*iterables): def izip(*iterables):
iterables = map(iter, iterables) iterables = map(iter, iterables)
while True: while iterables:
result = [i.next() for i in iterables] result = [i.next() for i in iterables]
yield tuple(result) yield tuple(result)
\end{verbatim} \end{verbatim}
\versionchanged[When no iterables are specified, returns a zero length
iterator instead of raising a TypeError exception]{2.4}
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{repeat}{object\optional{, times}} \begin{funcdesc}{repeat}{object\optional{, times}}
......
...@@ -87,7 +87,7 @@ class TestBasicOps(unittest.TestCase): ...@@ -87,7 +87,7 @@ class TestBasicOps(unittest.TestCase):
self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3))) self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3)))
self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3))) self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3)))
self.assertEqual(list(izip('abcdef')), zip('abcdef')) self.assertEqual(list(izip('abcdef')), zip('abcdef'))
self.assertRaises(TypeError, izip) self.assertEqual(list(izip()), zip())
self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, 3)
self.assertRaises(TypeError, izip, range(3), 3) self.assertRaises(TypeError, izip, range(3), 3)
# Check tuple re-use (implementation detail) # Check tuple re-use (implementation detail)
...@@ -199,6 +199,8 @@ class TestBasicOps(unittest.TestCase): ...@@ -199,6 +199,8 @@ class TestBasicOps(unittest.TestCase):
self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next) self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next)
def test_StopIteration(self): def test_StopIteration(self):
self.assertRaises(StopIteration, izip().next)
for f in (chain, cycle, izip): for f in (chain, cycle, izip):
self.assertRaises(StopIteration, f([]).next) self.assertRaises(StopIteration, f([]).next)
self.assertRaises(StopIteration, f(StopNow()).next) self.assertRaises(StopIteration, f(StopNow()).next)
...@@ -540,6 +542,9 @@ True ...@@ -540,6 +542,9 @@ True
>>> no(lambda x: x%2==0, [1, 2, 5, 9]) >>> no(lambda x: x%2==0, [1, 2, 5, 9])
False False
>>> quantify(lambda x: x%2==0, xrange(99))
50
>>> list(window('abc')) >>> list(window('abc'))
[('a', 'b'), ('b', 'c')] [('a', 'b'), ('b', 'c')]
......
...@@ -23,6 +23,9 @@ Extension modules ...@@ -23,6 +23,9 @@ Extension modules
Library Library
------- -------
- itertools.izip() with no arguments now returns an empty iterator instead
of raising a TypeError exception.
- _strptime.py now has a behind-the-scenes caching mechanism for the most - _strptime.py now has a behind-the-scenes caching mechanism for the most
recent TimeRE instance used along with the last five unique directive recent TimeRE instance used along with the last five unique directive
patterns. The overall module was also made more thread-safe. patterns. The overall module was also made more thread-safe.
......
...@@ -1510,12 +1510,6 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1510,12 +1510,6 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *result; PyObject *result;
int tuplesize = PySequence_Length(args); int tuplesize = PySequence_Length(args);
if (tuplesize < 1) {
PyErr_SetString(PyExc_TypeError,
"izip() requires at least one sequence");
return NULL;
}
/* args must be a tuple */ /* args must be a tuple */
assert(PyTuple_Check(args)); assert(PyTuple_Check(args));
...@@ -1598,6 +1592,8 @@ izip_next(izipobject *lz) ...@@ -1598,6 +1592,8 @@ izip_next(izipobject *lz)
PyObject *it; PyObject *it;
PyObject *item; PyObject *item;
if (tuplesize == 0)
return NULL;
if (result->ob_refcnt == 1) { if (result->ob_refcnt == 1) {
for (i=0 ; i < tuplesize ; i++) { for (i=0 ; i < tuplesize ; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i); it = PyTuple_GET_ITEM(lz->ittuple, i);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment