Hacker News new | past | comments | ask | show | jobs | submit login
What’s inside Python ‘for’ loop? (theailearner.com)
19 points by atulkrishna10 27 days ago | hide | past | web | favorite | 12 comments

Fun side-effect of this: if you're writing a Python interpreter, you need to implement exceptions+"try...except" before you can fully implement the "for" loop. And to implement this "except", you need classes and basic inheritance.

EDIT: the second code in the article is slightly wrong. The for loop is actually equivalent to:

    iter_object = iter(my_list)
    while True:
            number = next(iter_object)
        except StopIteration:
        sum += number # <-- the body of the original loop is here, outside the "try"
because if the body of the original "for" loop raises a "StopIteration", the loop doesn't catch it.

I'm not a particularly experienced programmer. It is a sign of my immature taste to find this ugly? The idea of assuming any exception thrown will be the exception we expect (outside iteration limits) seems like an unnecessary abuse of the exception system. I'm really surprised it's the way such a fundamental construct in the language is written.

Is the idea here that all other exceptions will be thrown at the line "iter_object= iter(my_list)"? I guess this makes sense. But it still makes me uncomfortable. Should I become more comfortable with writing constructs like this?

That’s not how it works.

“except StopIteration” only watches for the specific StopIteration exception coming from the next() call on the Iterator (the bit included in the try block).

If there was then an, for example, “except Error” line afterwards, then anything that causes an Error exception (ValueError, TypeError etc) would call those lines.

If you get any exception that has not been explicitly referenced in an except clause, then the program will halt, with that exception as the error output.

Duh- reading comprehension fail- cheers. Same question though, there is still something that makes me uncomfortable about using exceptions as an expected-case control flow structure (as in, this is expected to catch an exception once every for loop call). Is that something I should get over, and should I write more code that uses exceptions in this fashion?

Python's official implementation is very slow and they don't care about performance. I wouldn't try to take any lessons from the way Python is implemented.

You are correct that this use of exceptions is very bad code smell.

I'm not familiar with Python since I'm from Java background. In Java throwing exceptions is costly (like null check is preferred over catching NPE) since exception needs to get stacktrace which involves quite a lot of reflection.

Is this the case with python too? or throwing exception is "free" here?

Sort of. In Python the stacktrace is always built for every step you take in code, so exceptions are not particularly costly compared to other operations. Reflection is also not relatively more costly since types are objects just like everything else.

It could even be more efficient than return value checking in certain cases.

What's the overhead of exceptions like in Python? With .NET at least, especially with a debugger attached, this would have a pretty considerable impact!

Python is already so slow that it's comparable to normal iteration. But here's an example:

  timeit('next(x)', 'x = iter(range(1<<30))', number=1<<22)  # 0.22

  timeit('''try: raise StopIteration()
  except StopIteration: pass''', number=1<<22)  # 0.78

I pray for the day that Tensorflow has an official rust (or scala) api.

The "inside" part is slightly wrong, the payload is outside of the try/except clause:

    while True:
            number = next(iter_object)
        except StopIteration:
        sum += number
You can check this by throwing StopIteration inside the loop, and watching it propagate outside normally.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact