From e79511e6e7a8472b229dd60f1fa7934aec03ab1e Mon Sep 17 00:00:00 2001 From: Michael Blahay Date: Mon, 22 Jun 2020 01:19:35 -0400 Subject: [PATCH] #122 - Adding lstrip, rstrip, and strip for iterables (#253) * Adding lstrip, rstrip, strip functions * Adding tests for lstrip, rstrip, and strip * Adding strip to documenation. Fixing python2 compatibility * Fixing strip doc test * Fixing another strip doc test * Adding additional testing for lstrip, rstrip, and strip. Removing unnecessary import of sys --- boltons/iterutils.py | 94 +++++++++++++++++++++++++++++++++++++++++ docs/iterutils.rst | 6 +++ tests/test_iterutils.py | 26 ++++++++++++ 3 files changed, 126 insertions(+) diff --git a/boltons/iterutils.py b/boltons/iterutils.py index 157c2d4..cfa6087 100644 --- a/boltons/iterutils.py +++ b/boltons/iterutils.py @@ -177,6 +177,100 @@ def split_iter(src, sep=None, maxsplit=None): return +def lstrip(iterable, strip_value=None): + """Strips values from the beginning of an iterable. Stripped items will + match the value of the argument strip_value. Functionality is analigous + to that of the method str.lstrip. Returns a list. + + >>> lstrip(['Foo', 'Bar', 'Bam'], 'Foo') + ['Bar', 'Bam'] + + """ + return list(lstrip_iter(iterable, strip_value)) + + +def lstrip_iter(iterable, strip_value=None): + """Strips values from the beginning of an iterable. Stripped items will + match the value of the argument strip_value. Functionality is analigous + to that of the method str.lstrip. Returns a generator. + + >>> list(lstrip_iter(['Foo', 'Bar', 'Bam'], 'Foo')) + ['Bar', 'Bam'] + + """ + iterator = iter(iterable) + for i in iterator: + if i != strip_value: + yield i + break + for i in iterator: + yield i + + +def rstrip(iterable, strip_value=None): + """Strips values from the end of an iterable. Stripped items will + match the value of the argument strip_value. Functionality is analigous + to that of the method str.rstrip. Returns a list. + + >>> rstrip(['Foo', 'Bar', 'Bam'], 'Bam') + ['Foo', 'Bar'] + + """ + return list(rstrip_iter(iterable,strip_value)) + + +def rstrip_iter(iterable, strip_value=None): + """Strips values from the end of an iterable. Stripped items will + match the value of the argument strip_value. Functionality is analigous + to that of the method str.rstrip. Returns a generator. + + >>> list(rstrip_iter(['Foo', 'Bar', 'Bam'], 'Bam')) + ['Foo', 'Bar'] + + """ + iterator = iter(iterable) + for i in iterator: + if i == strip_value: + cache = list() + cache.append(i) + broken = False + for i in iterator: + if i == strip_value: + cache.append(i) + else: + broken = True + break + if not broken: # Return to caller here because the end of the + return # iterator has been reached + for t in cache: + yield t + yield i + + +def strip(iterable, strip_value=None): + """Strips values from the beginning and end of an iterable. Stripped items + will match the value of the argument strip_value. Functionality is + analigous to that of the method str.strip. Returns a list. + + >>> strip(['Fu', 'Foo', 'Bar', 'Bam', 'Fu'], 'Fu') + ['Foo', 'Bar', 'Bam'] + + """ + return list(strip_iter(iterable,strip_value)) + + +def strip_iter(iterable,strip_value=None): + """Strips values from the beginning and end of an iterable. Stripped items + will match the value of the argument strip_value. Functionality is + analigous to that of the method str.strip. Returns a generator. + + >>> list(strip_iter(['Fu', 'Foo', 'Bar', 'Bam', 'Fu'], 'Fu')) + ['Foo', 'Bar', 'Bam'] + + """ + return rstrip_iter(lstrip_iter(iterable,strip_value),strip_value) + + def chunked(src, size, count=None, **kw): """Returns a list of *count* chunks, each with *size* elements, generated from iterable *src*. If *src* is not evenly divisible by diff --git a/docs/iterutils.rst b/docs/iterutils.rst index b616fd4..92198e5 100644 --- a/docs/iterutils.rst +++ b/docs/iterutils.rst @@ -18,6 +18,12 @@ present in the standard library. .. autofunction:: split .. autofunction:: split_iter +.. autofunction:: strip +.. autofunction:: strip_iter +.. autofunction:: lstrip +.. autofunction:: lstrip_iter +.. autofunction:: rstrip +.. autofunction:: rstrip_iter .. autofunction:: chunked .. autofunction:: chunked_iter .. autofunction:: pairwise diff --git a/tests/test_iterutils.py b/tests/test_iterutils.py index 98d799d..0896f38 100644 --- a/tests/test_iterutils.py +++ b/tests/test_iterutils.py @@ -509,3 +509,29 @@ def test_chunked_bytes(): from boltons.iterutils import chunked assert chunked(b'123', 2) in (['12', '3'], [b'12', b'3']) + + +def test_lstrip(): + from boltons.iterutils import lstrip + + assert lstrip([0,1,0,2,0,3,0],0) == [1,0,2,0,3,0] + assert lstrip([0,0,0,1,0,2,0,3,0],0) == [1,0,2,0,3,0] + assert lstrip([]) == [] + + + +def test_rstrip(): + from boltons.iterutils import rstrip + + assert rstrip([0,1,0,2,0,3,0],0) == [0,1,0,2,0,3] + assert rstrip([0,1,0,2,0,3,0,0,0],0) == [0,1,0,2,0,3] + assert rstrip([]) == [] + + +def test_strip(): + from boltons.iterutils import strip + + assert strip([0,1,0,2,0,3,0],0) == [1,0,2,0,3] + assert strip([0,0,0,1,0,2,0,3,0,0,0],0) == [1,0,2,0,3] + assert strip([]) == [] +