Hacker News new | ask | show | jobs
by xmcqdpt2 1638 days ago
for/else is actually super useful for searching through a sequence or for iterating with a possible failure. Something like,

  for i in range(n):
      if search(i) == val:
          break
  else:
      raise KeyError("not found")
  found_index = i
It reduces the need for an additional flag. More importantly it makes it easier to ensure that the break condition is satisfied such that the loop variable can be used properly later on. Personally, I think an else condition should almost always be there for loops that gets broken early, similarly to always finishing if else chain with a final else.

ETA: Another pattern where it's really useful is to replace

  while True:
with a safer guaranteed terminating loop,

  for i in range(MAX_ITER):
     ...
  else:
    raise RuntimeError("exceeded max iterations")
1 comments

What's the advantage over the following?:

  for i in range(n):
      if search(i) == val:
          break
      raise KeyError("not found")
  found_index = i
That version doesn't work. It raises KeyError on the first iteration if the if statement is false.

The point of the for / else is that the else only gets evaluated when the for terminates without a break. So in the example you only get a KeyError if the search() never returns val.

Part of the confusion I guess is that the else: in my example is paired with for, not with if, Python indentation being significant etc.

Aha, thank you. Yes, it's plausible that my brain did pair the `else` with the `if`, even though it knew it was supposed to be paired with the `for`.

Before being introduced to `for`/`else`, I'd have written the example you gave as:

  result = None
  for i in range(n):
      if search(i) == val:
          result = i
  if not result:
      raise KeyError("not found")
I think this snippet would raise a KeyError whenever the index you're searching for is greater than 0.