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)
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.
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.
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.