[2.7] bpo-27212: Modify islice recipe to consume initial values prece… by csabella · Pull Request #6339 · python/cpython
Expand Up
@@ -802,6 +802,7 @@ def test_islice(self):
(10, 20, 3),
(10, 3, 20),
(10, 20),
(10, 10),
(10, 3),
(20,)
]:
Expand All
@@ -826,6 +827,10 @@ def test_islice(self):
self.assertEqual(list(islice(it, 3)), range(3))
self.assertEqual(list(it), range(3, 10))
it = iter(range(10)) self.assertEqual(list(islice(it, 3, 3)), []) self.assertEqual(list(it), range(3, 10))
# Test invalid arguments self.assertRaises(TypeError, islice, xrange(10)) self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4) Expand Down Expand Up @@ -1084,6 +1089,48 @@ def test_takewhile(self): self.assertEqual(list(takewhile(lambda x: x<5, [1,4,6,4,1])), [1,4])
class TestPurePythonRoughEquivalents(unittest.TestCase):
@staticmethod def islice(iterable, *args): s = slice(*args) start, stop, step = s.start or 0, s.stop or sys.maxint, s.step or 1 it = iter(xrange(start, stop, step)) try: nexti = next(it) except StopIteration: # Consume *iterable* up to the *start* position. for i, element in izip(xrange(start), iterable): pass return try: for i, element in enumerate(iterable): if i == nexti: yield element nexti = next(it) except StopIteration: # Consume to *stop*. for i, element in izip(xrange(i + 1, stop), iterable): pass
def test_islice_recipe(self): self.assertEqual(list(self.islice('ABCDEFG', 2)), list('AB')) self.assertEqual(list(self.islice('ABCDEFG', 2, 4)), list('CD')) self.assertEqual(list(self.islice('ABCDEFG', 2, None)), list('CDEFG')) self.assertEqual(list(self.islice('ABCDEFG', 0, None, 2)), list('ACEG')) # Test items consumed. it = iter(xrange(10)) self.assertEqual(list(self.islice(it, 3)), range(3)) self.assertEqual(list(it), range(3, 10)) it = iter(xrange(10)) self.assertEqual(list(self.islice(it, 3, 3)), []) self.assertEqual(list(it), range(3, 10)) # Test that slice finishes in predictable state. c = count() self.assertEqual(list(self.islice(c, 1, 3, 50)), [1]) self.assertEqual(next(c), 3)
class TestGC(unittest.TestCase):
def makecycle(self, iterator, container): Expand Down Expand Up @@ -1577,6 +1624,17 @@ def __init__(self, newarg=None, *args): ... "Return function(0), function(1), ..." ... return imap(function, count(start))
>>> import collections >>> def consume(iterator, n=None): ... "Advance the iterator n-steps ahead. If n is None, consume entirely." ... # Use functions that consume iterators at C speed. ... if n is None: ... # feed the entire iterator into a zero-length deque ... collections.deque(iterator, maxlen=0) ... else: ... # advance to the empty slice starting at position n ... next(islice(iterator, n, n), None)
>>> def nth(iterable, n, default=None): ... "Returns the nth item or a default value" ... return next(islice(iterable, n, None), default) Expand Down Expand Up @@ -1678,6 +1736,14 @@ def __init__(self, newarg=None, *args): >>> list(islice(tabulate(lambda x: 2*x), 4)) [0, 2, 4, 6]
>>> it = iter(xrange(10)) >>> consume(it, 3) >>> next(it) 3 >>> consume(it) >>> next(it, 'Done') 'Done'
>>> nth('abcde', 3) 'd'
Expand Down Expand Up @@ -1753,7 +1819,8 @@ def __init__(self, newarg=None, *args): def test_main(verbose=None): test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC, RegressionTests, LengthTransparency, SubclassWithKwargsTest, TestExamples) SubclassWithKwargsTest, TestExamples, TestPurePythonRoughEquivalents) test_support.run_unittest(*test_classes)
# verify reference counting Expand Down
it = iter(range(10)) self.assertEqual(list(islice(it, 3, 3)), []) self.assertEqual(list(it), range(3, 10))
# Test invalid arguments self.assertRaises(TypeError, islice, xrange(10)) self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4) Expand Down Expand Up @@ -1084,6 +1089,48 @@ def test_takewhile(self): self.assertEqual(list(takewhile(lambda x: x<5, [1,4,6,4,1])), [1,4])
class TestPurePythonRoughEquivalents(unittest.TestCase):
@staticmethod def islice(iterable, *args): s = slice(*args) start, stop, step = s.start or 0, s.stop or sys.maxint, s.step or 1 it = iter(xrange(start, stop, step)) try: nexti = next(it) except StopIteration: # Consume *iterable* up to the *start* position. for i, element in izip(xrange(start), iterable): pass return try: for i, element in enumerate(iterable): if i == nexti: yield element nexti = next(it) except StopIteration: # Consume to *stop*. for i, element in izip(xrange(i + 1, stop), iterable): pass
def test_islice_recipe(self): self.assertEqual(list(self.islice('ABCDEFG', 2)), list('AB')) self.assertEqual(list(self.islice('ABCDEFG', 2, 4)), list('CD')) self.assertEqual(list(self.islice('ABCDEFG', 2, None)), list('CDEFG')) self.assertEqual(list(self.islice('ABCDEFG', 0, None, 2)), list('ACEG')) # Test items consumed. it = iter(xrange(10)) self.assertEqual(list(self.islice(it, 3)), range(3)) self.assertEqual(list(it), range(3, 10)) it = iter(xrange(10)) self.assertEqual(list(self.islice(it, 3, 3)), []) self.assertEqual(list(it), range(3, 10)) # Test that slice finishes in predictable state. c = count() self.assertEqual(list(self.islice(c, 1, 3, 50)), [1]) self.assertEqual(next(c), 3)
class TestGC(unittest.TestCase):
def makecycle(self, iterator, container): Expand Down Expand Up @@ -1577,6 +1624,17 @@ def __init__(self, newarg=None, *args): ... "Return function(0), function(1), ..." ... return imap(function, count(start))
>>> import collections >>> def consume(iterator, n=None): ... "Advance the iterator n-steps ahead. If n is None, consume entirely." ... # Use functions that consume iterators at C speed. ... if n is None: ... # feed the entire iterator into a zero-length deque ... collections.deque(iterator, maxlen=0) ... else: ... # advance to the empty slice starting at position n ... next(islice(iterator, n, n), None)
>>> def nth(iterable, n, default=None): ... "Returns the nth item or a default value" ... return next(islice(iterable, n, None), default) Expand Down Expand Up @@ -1678,6 +1736,14 @@ def __init__(self, newarg=None, *args): >>> list(islice(tabulate(lambda x: 2*x), 4)) [0, 2, 4, 6]
>>> it = iter(xrange(10)) >>> consume(it, 3) >>> next(it) 3 >>> consume(it) >>> next(it, 'Done') 'Done'
>>> nth('abcde', 3) 'd'
Expand Down Expand Up @@ -1753,7 +1819,8 @@ def __init__(self, newarg=None, *args): def test_main(verbose=None): test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC, RegressionTests, LengthTransparency, SubclassWithKwargsTest, TestExamples) SubclassWithKwargsTest, TestExamples, TestPurePythonRoughEquivalents) test_support.run_unittest(*test_classes)
# verify reference counting Expand Down