By Brad Westermann via Discussions on Python.org at 16Jun2022 18:05:
OK let me give this a go at comprehension…because I just researched
what an explicit loop was and #mindblownemoji
Ah, you’ve discovered the notion of an iterable: anything which can be
iterated over.
So the explicit iterator in this is “row”?
Not quite.
table
is a list
containing smaller list
s. Any list
is iterable.
So in this line:
for row in table:
the expression table
gets your list-of-lists. That is iterable because
it is a list. The mechanics of the for-loop get an iterator from the
list. An iterator is a little mechanism which returns successive
values from its source iterable. The for-loop iterates over the
iterator. Each value from the iterator is assigned to the variable
row
in turn.
Let’s make this a bit more explicit:
- the iterable is a list, obtained from the expression at the end of
the for-loop (table
)
- the iterator is the additional new mechanism which iterates over the
list
- the for-loop obtains a new iterator from the iterable in order to
collect the list values
You can get an iterator directly from an iterable with the iter()
function:
>>> L = [1, 2, 3]
>>> type(L)
<class 'list'>
>>> it = iter(L)
>>> type(it)
<class 'list_iterator'>
The reason for this distinction is that you might have multiple
iterators for some iterable thing:
>>> for i in L:
... for j in L:
... print(i, j)
...
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
The outer for-loop gets an iterator for itself, and then each run of the
inner for-loop gets its own iterator, so that it can iterate over the
list elements independently to make the combinations above.
You can compare this with having just one iterator for both loops:
>>> it1 = iter(L)
>>> for i in it1:
... for j in it1:
... print(i, j)
...
1 2
1 3
Here, both loops “consume” the iterator, which becomes empty almost
immediately.
Cheers,
Cameron Simpson cs@cskk.id.au