OK, now for:

On Wed, May 13, 2020 at 7:50 PM Andrew Barnert <abarnert@yahoo.com> wrote:
Now onto the stuff that probably nobody else cares about:This is your mail agent being a pain again. You’re the one who said that, I quoted you saying it, and now you’re agreeing with yourself.

Of COURSE I agree ith myself :-) -- but I made that mistake partially because there was a big thread about this a while back -- and I wasn't the only one that said that.

> > Students often want to know why this doesn’t work:

    with open("file") as f:
        for line in file:
            do_stuff(line)
        for line in file:
            do_other_stuff(line)

… when this works fine:

    with open("file") as f:
        lines = file.readlines()
    for line in lines:
        do_stuff(line)
    for line in lines:
        do_other_stuff(line)

This question (or a variation on it) gets asked by novices every few day’s on StackOverflow; it’s one of the top common duplicates.

The answer is that files are iterators, while lists are… well, there is no word.

yes, there is -- they are "lists" :-) -- but if you want to be more general, they are Sequences.

But that’s the wrong generalization. Because sets also work the same way, and they aren’t Sequences. Nor are dict views, or many of the other kinds of things-that-can-be-iterated-over-and-over-independently.

But file.readline() does not return any of those objects. It returns a list. If you see this as an opportunity to teach about the iteration protocol, then sure, you'd want to make that distinction. But I think the file object is the wrong first example -- it's an oddball, having both the iteration protocol, AND methods for doing most of teh same things. Most iterables don't have the equivalent of readlines()  or readline() -- and in this case, I think THAT's the main sorce of confusion, rather than the iterable vs iterator distinction.

And you sure would want to make sure they "get" that readlines() is "greedy" -- it's like calling list() on an iterable. But why introduce that now?

<snip>

>> Which doesn't require me talking about iterators or iterables, or iter() or next()

> Sure, which is great right up until they ask the same question about why they can’t iterate twice over a map or zip.

Then THAT's the time to get into the iteration protocol -- map and zip are much more "clean" examples.

> > You can explain it anyway. In fact, you _have_ to give an explanation with analogies and examples and so on, and that would be true even if there were a word for what lists are. But it would be easier to explain if there were such a word, and if you could link that word to something in the glossary, and a chapter in the tutorial.

OK -- time for someone to come up with word for "Itererable that isn't an Iterator" -- I"d start using it :-)

> The word “view” _is_ great for things-like-dict-keys. That’s why I started off this thread asking for a view instead of an iterator, which I thought would be immediately clear. Unfortunately, it isn’t, or we wouldn’t even be having this discussion.

well it's as clear as maybe anything else -- at least after talking about it a while ...

- CHB


--
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython