1

Is there really no way to access the iterator object or its state from inside a for-loop?

Using pdb or ipdb for example, I can loop over and over again with n, but not see in which iteration I am (ex post, I mean; of course I could use enumerate, but only before starting the debugger).

def creates an object, and for does the same, doesn't it? But the function has a name - and the iterator has not, is not accessible in memory? By the way, is the function accessible from within its body without knowing the name?

(The answers to questions Python: access to iterator-object in for-loops and Iterate again within the for loop suggest that it's not possible, but it seems very strange, I was used to being able to inspect anything in python.)

Ilja
  • 2,024
  • 12
  • 28
  • This is awfully close to being a duplicate of some other questions, but I think the fact that you're asking how to do it in a _debugger_ - without modifying the code - makes it different enough. But I would suggest making it more clear that you are asking about debugging, not coding. (Otherwise the answer really is just to use `enumerate()`) – David Z Oct 02 '17 at 08:23
  • thank you, I tried to edit accodingly – Ilja Oct 02 '17 at 08:28
  • I'm not sure what you mean. Do you mean "access the iterator at all if you haven't stored it in a variable" or do you mean "access the internal state of the iterator when you stored it in a variable"? – MSeifert Oct 02 '17 at 09:33
  • originally I meant the former, to access it at all. Still more originally, I wondered that `break` and `continue` does not work in the debugger (I mean, does not interact with program flow, it's not just inserted between two lines), and if I could do it by accessing the iterator. – Ilja Oct 02 '17 at 09:42

1 Answers1

3

What do you think the 'internal state' of an iterator should look like?

  • If I'm iterating over lines read from a file it would be some file buffers and a character position within the current buffer.

  • If I iterate over a Fibonacci sequence it's going to be the last two values used to calculate the next.

  • If I iterate over a database query result it might be a database cursor used to read the next row.

  • If I iterate over a binary tree it will be pointers to nodes in the tree.

  • If I iterate over a list it might just be the index of the next element.

There's no common structure to iterators in Python. It is possible that some iterators might expose part of their internal structure but that would be specific to that particular iterator. The only thing you can do with an iterator is call next() on it to get the next element (or an Exception if there are no more).

If you want to be able to call next() from inside the for loop you should save a reference to the iterator, so instead of for v in someiterable: ... you do:

iterator = iter(someiterable)
for v in iterator:
    ... # Can refer to `v` or even call `v.next()` here ...

This works because there is a convention in Python that constructing an iterator from an existing iterator simply gives you the existing iterator. So the for loop won't do a separate iteration if you pass it something which is already an iterator. (Compare when you give it something which is merely iterable, each for loop will usually iterate independently.)

Duncan
  • 92,073
  • 11
  • 122
  • 156
  • Thank you for the response - I just noticed, that the last edit made my question title different from what I wanted to ask :) what confused me was that I cannot even call next, because I cannot access the object. – Ilja Oct 02 '17 at 09:27
  • your answer basically shows, that not all iterables are as simple as lists, right? Those are some interesting examples! By internal state you mean the variable that is used to calculate what to yield? – Ilja Oct 02 '17 at 09:34
  • Yes, the internal state can be pretty much anything used to calculate or retrieve the next value: and the next value need not exist in any form until it is needed. I added something about how to get access to the iterator inside the `for` loop. – Duncan Oct 02 '17 at 09:41
  • yes, I see this. I appreciate your time, but accepting this as an answer would make my question duplicate :) because saving the iterator beforehand is covered in the other two question. (I will link them here, because your explanation is more thorough I think). So the answer is: "no, I cant"? The body of the for-loop does not know which iterator called it? – Ilja Oct 02 '17 at 09:48