Not understanding itertools.dropwhile()

Steve D'Aprano steve+python at pearwood.info
Sat Apr 29 21:27:57 EDT 2017


On Sun, 30 Apr 2017 09:41 am, Jason Friedman wrote:

> <---- start code ---->
> 
> import itertools
> 
> data = """Line1
> Line2
> 
> Line4
> Line5"""
> 
> def test_to_start(s):
>     return "2" in s
> 
> for line in itertools.dropwhile(test_to_start, data.splitlines()):
>     print(line)
> 
> <---- end code ---->
> 
> I expect:
> 
> $ python3 dropwhile.py
> Line2
> 
> Line4
> Line5

dropwhile drops lines while the condition is true. Once the condition is
false, it stops dropping lines and returns them all. Since the condition
you give is not true at the start, nothing is dropped.

This example may explain how dropwhile is used:


py> lines = """line 1
... line 2
... line 3
... line 4
... another line
... and another line again
... and more lines
... line 8
... line 9
... and one more""".splitlines()
py> def startswith(text):
...     return text.startswith("line")
...
py> for line in itertools.dropwhile(startswith, lines):
...     print(line)
...
another line
and another line again
and more lines
line 8
line 9
and one more


Only lines at the start of the sequence will be dropped. Once the condition
becomes false, everything else is passed through. We can implement our own
version of dropwhile like this:

def my_dropwhile(condition, iterable):
    it = iter(iterable)
    for item in it:
        if not condition(item):
            yield item
            break
    for item in it: # anything remaining
        yield item


If you just want to remove lines, whether they are at the start or the
middle or the end, you should use either the built-in filter() or
itertools.filterfalse().




-- 
Steve
Emoji: a small, fuzzy, indistinct picture used to replace a clear and
perfectly comprehensible word.




More information about the Python-list mailing list