mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Move itertools izip() code to builtins as zip(). Complete the renaming.
This commit is contained in:
parent
c5a2eb949c
commit
736c0ab428
11 changed files with 281 additions and 476 deletions
|
@ -7,7 +7,6 @@ extern "C" {
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PySeqIter_Type;
|
PyAPI_DATA(PyTypeObject) PySeqIter_Type;
|
||||||
PyAPI_DATA(PyTypeObject) PyCallIter_Type;
|
PyAPI_DATA(PyTypeObject) PyCallIter_Type;
|
||||||
PyAPI_DATA(PyTypeObject) PyZipIter_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyCmpWrapper_Type;
|
PyAPI_DATA(PyTypeObject) PyCmpWrapper_Type;
|
||||||
|
|
||||||
#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_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 *);
|
PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *);
|
||||||
|
|
||||||
PyObject* _PyZip_CreateIter(PyObject* args);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@ Functions:
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
import warnings
|
import warnings
|
||||||
from itertools import filterfalse, izip
|
from itertools import filterfalse
|
||||||
|
|
||||||
__all__ = ["cmp","dircmp","cmpfiles"]
|
__all__ = ["cmp","dircmp","cmpfiles"]
|
||||||
|
|
||||||
|
@ -130,8 +130,8 @@ class dircmp:
|
||||||
self.right_list.sort()
|
self.right_list.sort()
|
||||||
|
|
||||||
def phase1(self): # Compute common names
|
def phase1(self): # Compute common names
|
||||||
a = dict(izip(map(os.path.normcase, self.left_list), self.left_list))
|
a = dict(zip(map(os.path.normcase, self.left_list), self.left_list))
|
||||||
b = dict(izip(map(os.path.normcase, self.right_list), self.right_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.common = list(map(a.__getitem__, filter(b.__contains__, a)))
|
||||||
self.left_only = list(map(a.__getitem__, filterfalse(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)))
|
self.right_only = list(map(b.__getitem__, filterfalse(a.__contains__, b)))
|
||||||
|
|
|
@ -129,7 +129,7 @@ From all times, sorting has always been a Great Art! :-)
|
||||||
__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge',
|
__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge',
|
||||||
'nlargest', 'nsmallest']
|
'nlargest', 'nsmallest']
|
||||||
|
|
||||||
from itertools import islice, repeat, count, izip, tee
|
from itertools import islice, repeat, count, tee
|
||||||
from operator import itemgetter, neg
|
from operator import itemgetter, neg
|
||||||
import bisect
|
import bisect
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ def nsmallest(n, iterable, key=None):
|
||||||
"""
|
"""
|
||||||
in1, in2 = tee(iterable)
|
in1, in2 = tee(iterable)
|
||||||
keys = in1 if key is None else map(key, in1)
|
keys = in1 if key is None else map(key, in1)
|
||||||
it = izip(keys, count(), in2) # decorate
|
it = zip(keys, count(), in2) # decorate
|
||||||
result = _nsmallest(n, it)
|
result = _nsmallest(n, it)
|
||||||
return list(map(itemgetter(2), result)) # undecorate
|
return list(map(itemgetter(2), result)) # undecorate
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ def nlargest(n, iterable, key=None):
|
||||||
"""
|
"""
|
||||||
in1, in2 = tee(iterable)
|
in1, in2 = tee(iterable)
|
||||||
keys = in1 if key is None else map(key, in1)
|
keys = in1 if key is None else map(key, in1)
|
||||||
it = izip(keys, map(neg, count()), in2) # decorate
|
it = zip(keys, map(neg, count()), in2) # decorate
|
||||||
result = _nlargest(n, it)
|
result = _nlargest(n, it)
|
||||||
return list(map(itemgetter(2), result)) # undecorate
|
return list(map(itemgetter(2), result)) # undecorate
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ class IterFuncStop:
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
from itertools import chain, map
|
from itertools import chain
|
||||||
def itermulti(seqn):
|
def itermulti(seqn):
|
||||||
'Test multiple tiers of iterators'
|
'Test multiple tiers of iterators'
|
||||||
return chain(map(lambda x:x, iterfunc(IterGen(Sequence(seqn)))))
|
return chain(map(lambda x:x, iterfunc(IterGen(Sequence(seqn)))))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import sys, itertools
|
import sys
|
||||||
import _ast
|
import _ast
|
||||||
|
|
||||||
def to_tuple(t):
|
def to_tuple(t):
|
||||||
|
@ -142,7 +142,7 @@ def run_tests():
|
||||||
for input, output, kind in ((exec_tests, exec_results, "exec"),
|
for input, output, kind in ((exec_tests, exec_results, "exec"),
|
||||||
(single_tests, single_results, "single"),
|
(single_tests, single_results, "single"),
|
||||||
(eval_tests, eval_results, "eval")):
|
(eval_tests, eval_results, "eval")):
|
||||||
for i, o in itertools.izip(input, output):
|
for i, o in zip(input, output):
|
||||||
ast_tree = compile(i, "?", kind, 0x400)
|
ast_tree = compile(i, "?", kind, 0x400)
|
||||||
tup = to_tuple(ast_tree)
|
tup = to_tuple(ast_tree)
|
||||||
assert tup == o, ("kind=%r\ninput=%r\nexpected=%r\ngot=%r" %
|
assert tup == o, ("kind=%r\ninput=%r\nexpected=%r\ngot=%r" %
|
||||||
|
|
|
@ -260,7 +260,7 @@ class S:
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
from itertools import chain, map
|
from itertools import chain
|
||||||
def L(seqn):
|
def L(seqn):
|
||||||
'Test multiple tiers of iterators'
|
'Test multiple tiers of iterators'
|
||||||
return chain(map(lambda x:x, R(Ig(G(seqn)))))
|
return chain(map(lambda x:x, R(Ig(G(seqn)))))
|
||||||
|
|
|
@ -8,8 +8,6 @@ import random
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
maxsize = test_support.MAX_Py_ssize_t
|
maxsize = test_support.MAX_Py_ssize_t
|
||||||
minsize = -maxsize-1
|
minsize = -maxsize-1
|
||||||
ifilter = filter
|
|
||||||
imap = map
|
|
||||||
|
|
||||||
def lzip(*args):
|
def lzip(*args):
|
||||||
return list(zip(*args))
|
return list(zip(*args))
|
||||||
|
@ -313,16 +311,16 @@ class TestBasicOps(unittest.TestCase):
|
||||||
keyfunc.skip = 1
|
keyfunc.skip = 1
|
||||||
self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)
|
self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)
|
||||||
|
|
||||||
def test_ifilter(self):
|
def test_filter(self):
|
||||||
self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4])
|
self.assertEqual(list(filter(isEven, range(6))), [0,2,4])
|
||||||
self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2])
|
self.assertEqual(list(filter(None, [0,1,0,2,0])), [1,2])
|
||||||
self.assertEqual(list(ifilter(bool, [0,1,0,2,0])), [1,2])
|
self.assertEqual(list(filter(bool, [0,1,0,2,0])), [1,2])
|
||||||
self.assertEqual(take(4, ifilter(isEven, count())), [0,2,4,6])
|
self.assertEqual(take(4, filter(isEven, count())), [0,2,4,6])
|
||||||
self.assertRaises(TypeError, ifilter)
|
self.assertRaises(TypeError, filter)
|
||||||
self.assertRaises(TypeError, ifilter, lambda x:x)
|
self.assertRaises(TypeError, filter, lambda x:x)
|
||||||
self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7)
|
self.assertRaises(TypeError, filter, lambda x:x, range(6), 7)
|
||||||
self.assertRaises(TypeError, ifilter, isEven, 3)
|
self.assertRaises(TypeError, filter, isEven, 3)
|
||||||
self.assertRaises(TypeError, next, ifilter(range(6), range(6)))
|
self.assertRaises(TypeError, next, filter(range(6), range(6)))
|
||||||
|
|
||||||
def test_filterfalse(self):
|
def test_filterfalse(self):
|
||||||
self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5])
|
self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5])
|
||||||
|
@ -335,28 +333,28 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, filterfalse, isEven, 3)
|
self.assertRaises(TypeError, filterfalse, isEven, 3)
|
||||||
self.assertRaises(TypeError, next, filterfalse(range(6), range(6)))
|
self.assertRaises(TypeError, next, filterfalse(range(6), range(6)))
|
||||||
|
|
||||||
def test_izip(self):
|
def test_zip(self):
|
||||||
# XXX This is rather silly now that builtin zip() calls izip()...
|
# XXX This is rather silly now that builtin zip() calls zip()...
|
||||||
ans = [(x,y) for x, y in izip('abc',count())]
|
ans = [(x,y) for x, y in zip('abc',count())]
|
||||||
self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)])
|
self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)])
|
||||||
self.assertEqual(list(izip('abc', range(6))), lzip('abc', range(6)))
|
self.assertEqual(list(zip('abc', range(6))), lzip('abc', range(6)))
|
||||||
self.assertEqual(list(izip('abcdef', range(3))), lzip('abcdef', range(3)))
|
self.assertEqual(list(zip('abcdef', range(3))), lzip('abcdef', range(3)))
|
||||||
self.assertEqual(take(3,izip('abcdef', count())), lzip('abcdef', range(3)))
|
self.assertEqual(take(3,zip('abcdef', count())), lzip('abcdef', range(3)))
|
||||||
self.assertEqual(list(izip('abcdef')), lzip('abcdef'))
|
self.assertEqual(list(zip('abcdef')), lzip('abcdef'))
|
||||||
self.assertEqual(list(izip()), lzip())
|
self.assertEqual(list(zip()), lzip())
|
||||||
self.assertRaises(TypeError, izip, 3)
|
self.assertRaises(TypeError, zip, 3)
|
||||||
self.assertRaises(TypeError, izip, range(3), 3)
|
self.assertRaises(TypeError, zip, range(3), 3)
|
||||||
# Check tuple re-use (implementation detail)
|
# Check tuple re-use (implementation detail)
|
||||||
self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')],
|
self.assertEqual([tuple(list(pair)) for pair in zip('abc', 'def')],
|
||||||
lzip('abc', 'def'))
|
lzip('abc', 'def'))
|
||||||
self.assertEqual([pair for pair in izip('abc', 'def')],
|
self.assertEqual([pair for pair in zip('abc', 'def')],
|
||||||
lzip('abc', 'def'))
|
lzip('abc', 'def'))
|
||||||
ids = list(map(id, izip('abc', 'def')))
|
ids = list(map(id, zip('abc', 'def')))
|
||||||
self.assertEqual(min(ids), max(ids))
|
self.assertEqual(min(ids), max(ids))
|
||||||
ids = list(map(id, list(izip('abc', 'def'))))
|
ids = list(map(id, list(zip('abc', 'def'))))
|
||||||
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
|
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
|
||||||
|
|
||||||
def test_iziplongest(self):
|
def test_ziplongest(self):
|
||||||
for args in [
|
for args in [
|
||||||
['abc', range(6)],
|
['abc', range(6)],
|
||||||
[range(6), 'abc'],
|
[range(6), 'abc'],
|
||||||
|
@ -378,7 +376,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(list(zip_longest('abcdef')), list(zip('abcdef')))
|
self.assertEqual(list(zip_longest('abcdef')), list(zip('abcdef')))
|
||||||
|
|
||||||
self.assertEqual(list(zip_longest('abc', 'defg', **{})),
|
self.assertEqual(list(zip_longest('abc', 'defg', **{})),
|
||||||
list(izip(list('abc')+[None], 'defg'))) # empty keyword dict
|
list(zip(list('abc')+[None], 'defg'))) # empty keyword dict
|
||||||
self.assertRaises(TypeError, zip_longest, 3)
|
self.assertRaises(TypeError, zip_longest, 3)
|
||||||
self.assertRaises(TypeError, zip_longest, range(3), 3)
|
self.assertRaises(TypeError, zip_longest, range(3), 3)
|
||||||
|
|
||||||
|
@ -448,29 +446,29 @@ class TestBasicOps(unittest.TestCase):
|
||||||
list(r)
|
list(r)
|
||||||
self.assertEqual(repr(r), 'repeat((1+0j), 0)')
|
self.assertEqual(repr(r), 'repeat((1+0j), 0)')
|
||||||
|
|
||||||
def test_imap(self):
|
def test_map(self):
|
||||||
self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
|
self.assertEqual(list(map(operator.pow, range(3), range(1,7))),
|
||||||
[0**1, 1**2, 2**3])
|
[0**1, 1**2, 2**3])
|
||||||
def tupleize(*args):
|
def tupleize(*args):
|
||||||
return args
|
return args
|
||||||
self.assertEqual(list(imap(tupleize, 'abc', range(5))),
|
self.assertEqual(list(map(tupleize, 'abc', range(5))),
|
||||||
[('a',0),('b',1),('c',2)])
|
[('a',0),('b',1),('c',2)])
|
||||||
self.assertEqual(list(imap(tupleize, 'abc', count())),
|
self.assertEqual(list(map(tupleize, 'abc', count())),
|
||||||
[('a',0),('b',1),('c',2)])
|
[('a',0),('b',1),('c',2)])
|
||||||
self.assertEqual(take(2,imap(tupleize, 'abc', count())),
|
self.assertEqual(take(2,map(tupleize, 'abc', count())),
|
||||||
[('a',0),('b',1)])
|
[('a',0),('b',1)])
|
||||||
self.assertEqual(list(imap(operator.pow, [])), [])
|
self.assertEqual(list(map(operator.pow, [])), [])
|
||||||
self.assertRaises(TypeError, imap)
|
self.assertRaises(TypeError, map)
|
||||||
self.assertRaises(TypeError, list, imap(None, range(3), range(3)))
|
self.assertRaises(TypeError, list, map(None, range(3), range(3)))
|
||||||
self.assertRaises(TypeError, imap, operator.neg)
|
self.assertRaises(TypeError, map, operator.neg)
|
||||||
self.assertRaises(TypeError, next, imap(10, range(5)))
|
self.assertRaises(TypeError, next, map(10, range(5)))
|
||||||
self.assertRaises(ValueError, next, imap(errfunc, [4], [5]))
|
self.assertRaises(ValueError, next, map(errfunc, [4], [5]))
|
||||||
self.assertRaises(TypeError, next, imap(onearg, [4], [5]))
|
self.assertRaises(TypeError, next, map(onearg, [4], [5]))
|
||||||
|
|
||||||
def test_starmap(self):
|
def test_starmap(self):
|
||||||
self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
|
self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
|
||||||
[0**1, 1**2, 2**3])
|
[0**1, 1**2, 2**3])
|
||||||
self.assertEqual(take(3, starmap(operator.pow, izip(count(), count(1)))),
|
self.assertEqual(take(3, starmap(operator.pow, zip(count(), count(1)))),
|
||||||
[0**1, 1**2, 2**3])
|
[0**1, 1**2, 2**3])
|
||||||
self.assertEqual(list(starmap(operator.pow, [])), [])
|
self.assertEqual(list(starmap(operator.pow, [])), [])
|
||||||
self.assertEqual(list(starmap(operator.pow, [iter([4,5])])), [4**5])
|
self.assertEqual(list(starmap(operator.pow, [iter([4,5])])), [4**5])
|
||||||
|
@ -641,9 +639,9 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertRaises(ReferenceError, getattr, p, '__class__')
|
self.assertRaises(ReferenceError, getattr, p, '__class__')
|
||||||
|
|
||||||
def test_StopIteration(self):
|
def test_StopIteration(self):
|
||||||
self.assertRaises(StopIteration, next, izip())
|
self.assertRaises(StopIteration, next, zip())
|
||||||
|
|
||||||
for f in (chain, cycle, izip, groupby):
|
for f in (chain, cycle, zip, groupby):
|
||||||
self.assertRaises(StopIteration, next, f([]))
|
self.assertRaises(StopIteration, next, f([]))
|
||||||
self.assertRaises(StopIteration, next, f(StopNow()))
|
self.assertRaises(StopIteration, next, f(StopNow()))
|
||||||
|
|
||||||
|
@ -659,7 +657,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
|
|
||||||
self.assertRaises(StopIteration, next, repeat(None, 0))
|
self.assertRaises(StopIteration, next, repeat(None, 0))
|
||||||
|
|
||||||
for f in (ifilter, filterfalse, imap, takewhile, dropwhile, starmap):
|
for f in (filter, filterfalse, map, takewhile, dropwhile, starmap):
|
||||||
self.assertRaises(StopIteration, next, f(lambda x:x, []))
|
self.assertRaises(StopIteration, next, f(lambda x:x, []))
|
||||||
self.assertRaises(StopIteration, next, f(lambda x:x, StopNow()))
|
self.assertRaises(StopIteration, next, f(lambda x:x, StopNow()))
|
||||||
|
|
||||||
|
@ -686,21 +684,21 @@ class TestGC(unittest.TestCase):
|
||||||
a = []
|
a = []
|
||||||
self.makecycle(groupby([a]*2, lambda x:x), a)
|
self.makecycle(groupby([a]*2, lambda x:x), a)
|
||||||
|
|
||||||
def test_ifilter(self):
|
def test_filter(self):
|
||||||
a = []
|
a = []
|
||||||
self.makecycle(ifilter(lambda x:True, [a]*2), a)
|
self.makecycle(filter(lambda x:True, [a]*2), a)
|
||||||
|
|
||||||
def test_filterfalse(self):
|
def test_filterfalse(self):
|
||||||
a = []
|
a = []
|
||||||
self.makecycle(filterfalse(lambda x:False, a), a)
|
self.makecycle(filterfalse(lambda x:False, a), a)
|
||||||
|
|
||||||
def test_izip(self):
|
def test_zip(self):
|
||||||
a = []
|
a = []
|
||||||
self.makecycle(izip([a]*2, [a]*3), a)
|
self.makecycle(zip([a]*2, [a]*3), a)
|
||||||
|
|
||||||
def test_imap(self):
|
def test_map(self):
|
||||||
a = []
|
a = []
|
||||||
self.makecycle(imap(lambda x:x, [a]*2), a)
|
self.makecycle(map(lambda x:x, [a]*2), a)
|
||||||
|
|
||||||
def test_islice(self):
|
def test_islice(self):
|
||||||
a = []
|
a = []
|
||||||
|
@ -792,7 +790,7 @@ class S:
|
||||||
|
|
||||||
def L(seqn):
|
def L(seqn):
|
||||||
'Test multiple tiers of iterators'
|
'Test multiple tiers of iterators'
|
||||||
return chain(imap(lambda x:x, R(Ig(G(seqn)))))
|
return chain(map(lambda x:x, R(Ig(G(seqn)))))
|
||||||
|
|
||||||
|
|
||||||
class TestVariousIteratorArgs(unittest.TestCase):
|
class TestVariousIteratorArgs(unittest.TestCase):
|
||||||
|
@ -831,14 +829,14 @@ class TestVariousIteratorArgs(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, groupby, N(s))
|
self.assertRaises(TypeError, groupby, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, list, groupby(E(s)))
|
self.assertRaises(ZeroDivisionError, list, groupby(E(s)))
|
||||||
|
|
||||||
def test_ifilter(self):
|
def test_filter(self):
|
||||||
for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)):
|
for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)):
|
||||||
for g in (G, I, Ig, S, L, R):
|
for g in (G, I, Ig, S, L, R):
|
||||||
self.assertEqual(list(ifilter(isEven, g(s))),
|
self.assertEqual(list(filter(isEven, g(s))),
|
||||||
[x for x in g(s) if isEven(x)])
|
[x for x in g(s) if isEven(x)])
|
||||||
self.assertRaises(TypeError, ifilter, isEven, X(s))
|
self.assertRaises(TypeError, filter, isEven, X(s))
|
||||||
self.assertRaises(TypeError, ifilter, isEven, N(s))
|
self.assertRaises(TypeError, filter, isEven, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, list, ifilter(isEven, E(s)))
|
self.assertRaises(ZeroDivisionError, list, filter(isEven, E(s)))
|
||||||
|
|
||||||
def test_filterfalse(self):
|
def test_filterfalse(self):
|
||||||
for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)):
|
for s in (range(10), range(0), range(1000), (7,11), range(2000,2200,5)):
|
||||||
|
@ -849,16 +847,16 @@ class TestVariousIteratorArgs(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, filterfalse, isEven, N(s))
|
self.assertRaises(TypeError, filterfalse, isEven, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, list, filterfalse(isEven, E(s)))
|
self.assertRaises(ZeroDivisionError, list, filterfalse(isEven, E(s)))
|
||||||
|
|
||||||
def test_izip(self):
|
def test_zip(self):
|
||||||
for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
|
for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
|
||||||
for g in (G, I, Ig, S, L, R):
|
for g in (G, I, Ig, S, L, R):
|
||||||
self.assertEqual(list(izip(g(s))), lzip(g(s)))
|
self.assertEqual(list(zip(g(s))), lzip(g(s)))
|
||||||
self.assertEqual(list(izip(g(s), g(s))), lzip(g(s), g(s)))
|
self.assertEqual(list(zip(g(s), g(s))), lzip(g(s), g(s)))
|
||||||
self.assertRaises(TypeError, izip, X(s))
|
self.assertRaises(TypeError, zip, X(s))
|
||||||
self.assertRaises(TypeError, izip, N(s))
|
self.assertRaises(TypeError, zip, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, list, izip(E(s)))
|
self.assertRaises(ZeroDivisionError, list, zip(E(s)))
|
||||||
|
|
||||||
def test_iziplongest(self):
|
def test_ziplongest(self):
|
||||||
for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
|
for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
|
||||||
for g in (G, I, Ig, S, L, R):
|
for g in (G, I, Ig, S, L, R):
|
||||||
self.assertEqual(list(zip_longest(g(s))), list(zip(g(s))))
|
self.assertEqual(list(zip_longest(g(s))), list(zip(g(s))))
|
||||||
|
@ -867,16 +865,16 @@ class TestVariousIteratorArgs(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, zip_longest, N(s))
|
self.assertRaises(TypeError, zip_longest, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, list, zip_longest(E(s)))
|
self.assertRaises(ZeroDivisionError, list, zip_longest(E(s)))
|
||||||
|
|
||||||
def test_imap(self):
|
def test_map(self):
|
||||||
for s in (range(10), range(0), range(100), (7,11), range(20,50,5)):
|
for s in (range(10), range(0), range(100), (7,11), range(20,50,5)):
|
||||||
for g in (G, I, Ig, S, L, R):
|
for g in (G, I, Ig, S, L, R):
|
||||||
self.assertEqual(list(imap(onearg, g(s))),
|
self.assertEqual(list(map(onearg, g(s))),
|
||||||
[onearg(x) for x in g(s)])
|
[onearg(x) for x in g(s)])
|
||||||
self.assertEqual(list(imap(operator.pow, g(s), g(s))),
|
self.assertEqual(list(map(operator.pow, g(s), g(s))),
|
||||||
[x**x for x in g(s)])
|
[x**x for x in g(s)])
|
||||||
self.assertRaises(TypeError, imap, onearg, X(s))
|
self.assertRaises(TypeError, map, onearg, X(s))
|
||||||
self.assertRaises(TypeError, imap, onearg, N(s))
|
self.assertRaises(TypeError, map, onearg, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, list, imap(onearg, E(s)))
|
self.assertRaises(ZeroDivisionError, list, map(onearg, E(s)))
|
||||||
|
|
||||||
def test_islice(self):
|
def test_islice(self):
|
||||||
for s in ("12345", "", range(1000), ('do', 1.2), range(2000,2200,5)):
|
for s in ("12345", "", range(1000), ('do', 1.2), range(2000,2200,5)):
|
||||||
|
@ -953,8 +951,8 @@ class RegressionTests(unittest.TestCase):
|
||||||
return value
|
return value
|
||||||
items = list(tuple2)
|
items = list(tuple2)
|
||||||
items[1:1] = list(tuple1)
|
items[1:1] = list(tuple1)
|
||||||
gen = imap(g, items)
|
gen = map(g, items)
|
||||||
z = izip(*[gen]*len(tuple1))
|
z = zip(*[gen]*len(tuple1))
|
||||||
next(z)
|
next(z)
|
||||||
|
|
||||||
def f(t):
|
def f(t):
|
||||||
|
@ -1001,7 +999,7 @@ class RegressionTests(unittest.TestCase):
|
||||||
class SubclassWithKwargsTest(unittest.TestCase):
|
class SubclassWithKwargsTest(unittest.TestCase):
|
||||||
def test_keywords_in_subclass(self):
|
def test_keywords_in_subclass(self):
|
||||||
# count is not subclassable...
|
# count is not subclassable...
|
||||||
for cls in (repeat, izip, ifilter, filterfalse, chain, imap,
|
for cls in (repeat, zip, filter, filterfalse, chain, map,
|
||||||
starmap, islice, takewhile, dropwhile, cycle):
|
starmap, islice, takewhile, dropwhile, cycle):
|
||||||
class Subclass(cls):
|
class Subclass(cls):
|
||||||
def __init__(self, newarg=None, *args):
|
def __init__(self, newarg=None, *args):
|
||||||
|
@ -1017,7 +1015,7 @@ libreftest = """ Doctest for examples in the library reference: libitertools.tex
|
||||||
|
|
||||||
|
|
||||||
>>> amounts = [120.15, 764.05, 823.14]
|
>>> amounts = [120.15, 764.05, 823.14]
|
||||||
>>> for checknum, amount in izip(count(1200), amounts):
|
>>> for checknum, amount in zip(count(1200), amounts):
|
||||||
... print('Check %d is for $%.2f' % (checknum, amount))
|
... print('Check %d is for $%.2f' % (checknum, amount))
|
||||||
...
|
...
|
||||||
Check 1200 is for $120.15
|
Check 1200 is for $120.15
|
||||||
|
@ -1025,7 +1023,7 @@ Check 1201 is for $764.05
|
||||||
Check 1202 is for $823.14
|
Check 1202 is for $823.14
|
||||||
|
|
||||||
>>> import operator
|
>>> import operator
|
||||||
>>> for cube in imap(operator.pow, range(1,4), repeat(3)):
|
>>> for cube in map(operator.pow, range(1,4), repeat(3)):
|
||||||
... print(cube)
|
... print(cube)
|
||||||
...
|
...
|
||||||
1
|
1
|
||||||
|
@ -1070,14 +1068,14 @@ Samuele
|
||||||
... return list(islice(seq, n))
|
... return list(islice(seq, n))
|
||||||
|
|
||||||
>>> def enumerate(iterable):
|
>>> def enumerate(iterable):
|
||||||
... return izip(count(), iterable)
|
... return zip(count(), iterable)
|
||||||
|
|
||||||
>>> def tabulate(function):
|
>>> def tabulate(function):
|
||||||
... "Return function(0), function(1), ..."
|
... "Return function(0), function(1), ..."
|
||||||
... return imap(function, count())
|
... return map(function, count())
|
||||||
|
|
||||||
>>> def iteritems(mapping):
|
>>> def iteritems(mapping):
|
||||||
... return izip(mapping.keys(), mapping.values())
|
... return zip(mapping.keys(), mapping.values())
|
||||||
|
|
||||||
>>> def nth(iterable, n):
|
>>> def nth(iterable, n):
|
||||||
... "Returns the nth item"
|
... "Returns the nth item"
|
||||||
|
@ -1091,19 +1089,19 @@ Samuele
|
||||||
|
|
||||||
>>> def any(seq, pred=None):
|
>>> def any(seq, pred=None):
|
||||||
... "Returns True if pred(x) is true for at least one element in the iterable"
|
... "Returns True if pred(x) is true for at least one element in the iterable"
|
||||||
... for elem in ifilter(pred, seq):
|
... for elem in filter(pred, seq):
|
||||||
... return True
|
... return True
|
||||||
... return False
|
... return False
|
||||||
|
|
||||||
>>> def no(seq, pred=None):
|
>>> def no(seq, pred=None):
|
||||||
... "Returns True if pred(x) is false for every element in the iterable"
|
... "Returns True if pred(x) is false for every element in the iterable"
|
||||||
... for elem in ifilter(pred, seq):
|
... for elem in filter(pred, seq):
|
||||||
... return False
|
... return False
|
||||||
... return True
|
... return True
|
||||||
|
|
||||||
>>> def quantify(seq, pred=None):
|
>>> def quantify(seq, pred=None):
|
||||||
... "Count how many times the predicate is true in the sequence"
|
... "Count how many times the predicate is true in the sequence"
|
||||||
... return sum(imap(pred, seq))
|
... return sum(map(pred, seq))
|
||||||
|
|
||||||
>>> def padnone(seq):
|
>>> def padnone(seq):
|
||||||
... "Returns the sequence elements and then returns None indefinitely"
|
... "Returns the sequence elements and then returns None indefinitely"
|
||||||
|
@ -1114,7 +1112,7 @@ Samuele
|
||||||
... return chain(*repeat(seq, n))
|
... return chain(*repeat(seq, n))
|
||||||
|
|
||||||
>>> def dotproduct(vec1, vec2):
|
>>> def dotproduct(vec1, vec2):
|
||||||
... return sum(imap(operator.mul, vec1, vec2))
|
... return sum(map(operator.mul, vec1, vec2))
|
||||||
|
|
||||||
>>> def flatten(listOfLists):
|
>>> def flatten(listOfLists):
|
||||||
... return list(chain(*listOfLists))
|
... return list(chain(*listOfLists))
|
||||||
|
@ -1134,7 +1132,7 @@ Samuele
|
||||||
... next(b)
|
... next(b)
|
||||||
... except StopIteration:
|
... except StopIteration:
|
||||||
... pass
|
... pass
|
||||||
... return izip(a, b)
|
... return zip(a, b)
|
||||||
|
|
||||||
This is not part of the examples but it tests to make sure the definitions
|
This is not part of the examples but it tests to make sure the definitions
|
||||||
perform as purported.
|
perform as purported.
|
||||||
|
@ -1180,7 +1178,7 @@ False
|
||||||
[8, 8, 8, 8, 8]
|
[8, 8, 8, 8, 8]
|
||||||
|
|
||||||
>>> import random
|
>>> import random
|
||||||
>>> take(5, imap(int, repeatfunc(random.random)))
|
>>> take(5, map(int, repeatfunc(random.random)))
|
||||||
[0, 0, 0, 0, 0]
|
[0, 0, 0, 0, 0]
|
||||||
|
|
||||||
>>> list(pairwise('abcd'))
|
>>> list(pairwise('abcd'))
|
||||||
|
|
|
@ -72,7 +72,7 @@ Core and Builtins
|
||||||
|
|
||||||
- Issue #1969: split and rsplit in bytearray are inconsistent
|
- 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.
|
Use zip() instead.
|
||||||
|
|
||||||
- Issue #1769: Now int("- 1") is not allowed any more.
|
- Issue #1769: Now int("- 1") is not allowed any more.
|
||||||
|
@ -123,6 +123,10 @@ Core and Builtins
|
||||||
Extension Modules
|
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()
|
- Issue #1762972: Readded the reload() function as imp.reload()
|
||||||
|
|
||||||
- Bug #2111: mmap segfaults when trying to write a block opened with PROT_READ
|
- Bug #2111: mmap segfaults when trying to write a block opened with PROT_READ
|
||||||
|
|
|
@ -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 ************************************************************/
|
/* repeat object ************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2675,7 +2488,7 @@ static PyTypeObject repeat_type = {
|
||||||
PyObject_GC_Del, /* tp_free */
|
PyObject_GC_Del, /* tp_free */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* iziplongest object ************************************************************/
|
/* ziplongest object ************************************************************/
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
|
@ -2686,14 +2499,14 @@ typedef struct {
|
||||||
PyObject *ittuple; /* tuple of iterators */
|
PyObject *ittuple; /* tuple of iterators */
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
PyObject *fillvalue;
|
PyObject *fillvalue;
|
||||||
} iziplongestobject;
|
} ziplongestobject;
|
||||||
|
|
||||||
static PyTypeObject iziplongest_type;
|
static PyTypeObject ziplongest_type;
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
iziplongestobject *lz;
|
ziplongestobject *lz;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *ittuple; /* tuple of iterators */
|
PyObject *ittuple; /* tuple of iterators */
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
@ -2741,8 +2554,8 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyTuple_SET_ITEM(result, i, Py_None);
|
PyTuple_SET_ITEM(result, i, Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create iziplongestobject structure */
|
/* create ziplongestobject structure */
|
||||||
lz = (iziplongestobject *)type->tp_alloc(type, 0);
|
lz = (ziplongestobject *)type->tp_alloc(type, 0);
|
||||||
if (lz == NULL) {
|
if (lz == NULL) {
|
||||||
Py_DECREF(ittuple);
|
Py_DECREF(ittuple);
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
@ -2758,7 +2571,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zip_longest_dealloc(iziplongestobject *lz)
|
zip_longest_dealloc(ziplongestobject *lz)
|
||||||
{
|
{
|
||||||
PyObject_GC_UnTrack(lz);
|
PyObject_GC_UnTrack(lz);
|
||||||
Py_XDECREF(lz->ittuple);
|
Py_XDECREF(lz->ittuple);
|
||||||
|
@ -2768,7 +2581,7 @@ zip_longest_dealloc(iziplongestobject *lz)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zip_longest_traverse(iziplongestobject *lz, visitproc visit, void *arg)
|
zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(lz->ittuple);
|
Py_VISIT(lz->ittuple);
|
||||||
Py_VISIT(lz->result);
|
Py_VISIT(lz->result);
|
||||||
|
@ -2777,7 +2590,7 @@ zip_longest_traverse(iziplongestobject *lz, visitproc visit, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zip_longest_next(iziplongestobject *lz)
|
zip_longest_next(ziplongestobject *lz)
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
Py_ssize_t tuplesize = lz->tuplesize;
|
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\
|
defaults to None or can be specified by a keyword argument.\n\
|
||||||
");
|
");
|
||||||
|
|
||||||
static PyTypeObject iziplongest_type = {
|
static PyTypeObject ziplongest_type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
"itertools.zip_longest", /* tp_name */
|
"itertools.zip_longest", /* tp_name */
|
||||||
sizeof(iziplongestobject), /* tp_basicsize */
|
sizeof(ziplongestobject), /* tp_basicsize */
|
||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)zip_longest_dealloc, /* tp_dealloc */
|
(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\
|
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
|
||||||
\n\
|
\n\
|
||||||
Iterators terminating on the shortest input sequence:\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\
|
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\
|
filterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
|
||||||
islice(seq, [start,] stop [, step]) --> elements from\n\
|
islice(seq, [start,] stop [, step]) --> elements from\n\
|
||||||
|
@ -2949,8 +2761,7 @@ inititertools(void)
|
||||||
&chain_type,
|
&chain_type,
|
||||||
&filterfalse_type,
|
&filterfalse_type,
|
||||||
&count_type,
|
&count_type,
|
||||||
&izip_type,
|
&ziplongest_type,
|
||||||
&iziplongest_type,
|
|
||||||
&product_type,
|
&product_type,
|
||||||
&repeat_type,
|
&repeat_type,
|
||||||
&groupby_type,
|
&groupby_type,
|
||||||
|
|
|
@ -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 */
|
|
||||||
};
|
|
||||||
|
|
|
@ -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.).");
|
is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).");
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
typedef struct {
|
||||||
builtin_zip(PyObject *self, PyObject *args)
|
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 */
|
/* args must be a tuple */
|
||||||
assert(PyTuple_Check(args));
|
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,
|
PyDoc_STRVAR(zip_doc,
|
||||||
"zip(it1 [, it2 [...]]) -> iter([(it1[0], it2[0] ...), ...])\n\
|
"zip(iter1 [,iter2 [...]]) --> zip object\n\
|
||||||
\n\
|
\n\
|
||||||
Return an iterator yielding tuples, where each tuple contains the\n\
|
Return a zip object whose .__next__() method returns a tuple where\n\
|
||||||
corresponding element from each of the argument iterables.\n\
|
the i-th element comes from the i-th iterable argument. The .__next__()\n\
|
||||||
The returned iterator ends when the shortest argument iterable is exhausted.\n\
|
method continues until the shortest iterable in the argument sequence\n\
|
||||||
(This is identical to itertools.izip().)");
|
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[] = {
|
static PyMethodDef builtin_methods[] = {
|
||||||
|
@ -2028,7 +2192,6 @@ static PyMethodDef builtin_methods[] = {
|
||||||
{"sorted", (PyCFunction)builtin_sorted, METH_VARARGS | METH_KEYWORDS, sorted_doc},
|
{"sorted", (PyCFunction)builtin_sorted, METH_VARARGS | METH_KEYWORDS, sorted_doc},
|
||||||
{"sum", builtin_sum, METH_VARARGS, sum_doc},
|
{"sum", builtin_sum, METH_VARARGS, sum_doc},
|
||||||
{"vars", builtin_vars, METH_VARARGS, vars_doc},
|
{"vars", builtin_vars, METH_VARARGS, vars_doc},
|
||||||
{"zip", builtin_zip, METH_VARARGS, zip_doc},
|
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2097,6 +2260,7 @@ _PyBuiltin_Init(void)
|
||||||
SETBUILTIN("super", &PySuper_Type);
|
SETBUILTIN("super", &PySuper_Type);
|
||||||
SETBUILTIN("tuple", &PyTuple_Type);
|
SETBUILTIN("tuple", &PyTuple_Type);
|
||||||
SETBUILTIN("type", &PyType_Type);
|
SETBUILTIN("type", &PyType_Type);
|
||||||
|
SETBUILTIN("zip", &PyZip_Type);
|
||||||
debug = PyBool_FromLong(Py_OptimizeFlag == 0);
|
debug = PyBool_FromLong(Py_OptimizeFlag == 0);
|
||||||
if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
|
if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
|
||||||
Py_XDECREF(debug);
|
Py_XDECREF(debug);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue