Topic: https://intoli.com/blog/for-else-in-python/
hide preview

What's next? verify your email address for reply notifications!

2aey2ix7 6y, 54d ago [edited]

Using filter and next is probably the worst way of replacing for-else. Your "solution" is much harder to read and understand. Much better to use a separate function with an early return. Then you remove the else clause and dedent the code in the else block one level. Like so:

def song_fn():
    for song in songs:
        if song.name == next_song_name:
            next_song = song
            return
    next_song = download_song(next_song_name)
remark link
hide preview

What's next? verify your email address for reply notifications!

andre 6y, 53d ago [edited]

Sure, that works, too. My point is that there's plenty of alternatives available to you, even if filter() is not your thing. For example, you could achieve the same results as in the filter() example with a generator expression, next(), and a try-except block.

try:
    next_song = next(song for song in songs if song.name == next_song_name)
except StopIteration:
    next_song = download_song(next_song_name)

The generator expression will create an iterator, and next() will pick out the first match. If no match exists, a StopIteration error is raised, giving us a chance to download the missing song.

hide preview

What's next? verify your email address for reply notifications!

UTENzmsd 6y, 53d ago

At the end of just about every non-trivial loop, I always find myself needing to know why/how the loop ended inorder to decide what to do next. While I was unaware of this in Python, I'll certainly use it in the future. Thanks!

hide preview

What's next? verify your email address for reply notifications!

unverified 5y, 248d ago

Ouch, I "love" when people set to expertly explain some finicky concept only to fail horribly, misinforming tons of poor souls in the process. I hope you haven't tried / won't try to "educate" us on "closures vs. anonymous functions vs. first-class functions" (a pet peeve of mine, lotsa smart people insert lotsa dumb mistakes into this one).

while True:
    # Do some work here, possibly `break`.
    if condition:
        continue
    else:
        # Do stuff if the condition isn't met.
        break

is utter bullshit. Firstly, "if not condition: do_stuff(); break" would be better. Aaaand, you can't emulate the behavior with plain Python code, exactly because the behaviour is special. You'd need something like this:

_BREAKED__ = False
while condition:
    try:
        # do stuff; transform any breaks in this section into: raise OurBreakException()
    except OurBreakException:
        __BREAKED__ = True
        break
if not __BREAKED__:
    # "else:" part

The for replacement would be even worse.

remark link
hide preview

What's next? verify your email address for reply notifications!

evan 5y, 242d ago

The code example that you're criticizing is a direct port of the C code that Raymond Hettinger posted to explain how Python loops were implemented in 1991. You're welcome to think that another construction would have been better, but that doesn't change the fact this is the reason that for-else clauses ended up in Python.

hide preview

What's next? verify your email address for reply notifications!

unverified 5y, 56d ago

I think your "solution" proves that the for-else has indeed its use, just this alternative is so poorly written.

Don't try to find "smart" ways to express a simple idea, making that unreadable to others and difficult to maintain.

hide preview

What's next? verify your email address for reply notifications!