FAQ: Code Challenge: Loops - Delete Starting Even Numbers

Hm. I’m not sure I agree with both using an iterator and then going back to the start to search for the index - I would rather only consume from the iterator, and anything that has been dropped can be forgotten.

If there’s a rope sticking out of a wall (an iterator), then I could pull at it until there’s a non-even value, and then either turn the rest into a list, or let whoever wants the remaining values pull out the rest of the rope when and if they want it.

Sidenote:
Almost cheating, but interesting enough, and possibly not immediately obvious even knowing it exists - itertools.dropwhile implements a more general version of this problem: dropwhile(even, lst)

1 Like

itertools.dropwhile

Interesting. Thanks for that.

One could use range to expose the indices.

with `range()`
>>> def delete_starting_evens(lst):
	try:
		return lst[next(i for i in range(len(lst)) if lst[i] % 2):]
	except StopIteration:
		return []

	
>>> delete_starting_evens(a)
[51, 60, 75]
>>> delete_starting_evens(b)
[]
>>> 

Or, use enumerate to expose both index and value…

with `enumerate()`
>>> def delete_starting_evens(lst):
	try:
		return lst[next(i for i, x in enumerate(lst) if x % 2):]
	except StopIteration:
		return []

	
>>> delete_starting_evens(a)
[51, 60, 75]
>>> delete_starting_evens(b)
[]
>>> 

Either of which make more sense than the earlier example given your advice.

1 Like

That’s a smaller amount of loops.
If you’re going to do list slicing, I’d really like to see finding the start location as a separate step (separate line, put result in variable)
And then, if you’re going to use iterators as a strategy of finding the first value - fine.

I'm looking for something more like this for using iterators
def delete_starting_evens(xs):
    xs = iter(xs)
    for x in xs:
        if x % 2 != 0:
            yield x
            yield from xs
            return
Or this, using find and slice
def delete_starting_evens(xs):
    for i, x in enumerate(xs):
        if x % 2 != 0:
            return xs[i:]
    return []
Or after abstracting out some stuff - if the language doesn't come with the kind of words to describe what's wanted then putting it all in one function may make it a bit difficult to read. Defining the words you want allows for expressing things in nicer ways.
def even(n):
    return n % 2 == 0


def not_(f):
    def f_(*args, **kwargs):
        return not f(*args, **kwargs)
    return f_


def find(f, xs):
    for i, x in enumerate(xs):
        if f(x):
            return i
    return i+1


def delete_starting_evens(xs):
    first_non_even = find(not_(even), xs)
    return xs[first_non_even:]
But obviously the right word here already exists in dropwhile, to the point where this whole function shouldn't exist at all, dropwhile covers it.
from itertools import dropwhile


def even(n):
    return n % 2 == 0


def delete_starting_evens(xs):
    return dropwhile(even, xs)
2 Likes

The second example is how I originally solved this one. Love going down the rabbit hole and seeing what pops up.

Thanks again for the great examples; and, I won’t argue with your last point. It makes the most sense. You’d think I had an aversion to libraries, or something the way I never reach for them.

1 Like

A post was merged into an existing topic: Why doesn’t iterating with for work while removing items from a list?

27 posts were merged into an existing topic: Why doesn’t iterating with for work while removing items from a list?

3 posts were split to a new topic: Infinite loop [solved]

4 posts were split to a new topic: How does break work? [solved]

8 posts were split to a new topic: Code challenge lists - improving my solution [solved]

3 posts were split to a new topic: Using continue in a while loop [solved]

7 posts were split to a new topic: How does this code loop I wrote work?

4 posts were split to a new topic: Why does my loop skip indexes of my list?

2 posts were merged into an existing topic: Why is len(lst) > 0 necessary for solving the list challenge?

4 posts were split to a new topic: Why doesn’t my code work how I expected?

15 posts were split to a new topic: Question on loops

5 posts were split to a new topic: Can you help me convert this into list comprehension?

3 posts were split to a new topic: Why do I get ‘None’?

2 posts were split to a new topic: I don’t know what my code does?

4 posts were merged into an existing topic: Why doesn’t iterating with for work while removing items from a list?

4 posts were merged into an existing topic: Why is len(lst) > 0 necessary for solving the list challenge?