How do you refer to an iterator in docs?

R

Roy Smith

Let's say I have a function which takes a list of words. I might write
the docstring for it something like:

def foo(words):
"Foo-ify words (which must be a list)"

What if I want words to be the more general case of something you can
iterate over? How do people talk about that in docstrings? Do you say
"something which can be iterated over to yield words", "an iterable over
words", or what?

I can think of lots of ways to describe the concept, but most of them
seem rather verbose and awkward compared to "a list of words", "a
dictionary whose keys are words", etc.
 
J

Jacob MacDonald

Let's say I have a function which takes a list of words. I might write
the docstring for it something like:

def foo(words):
"Foo-ify words (which must be a list)"

What if I want words to be the more general case of something you can
iterate over? How do people talk about that in docstrings? Do you say
"something which can be iterated over to yield words", "an iterable over
words", or what?

I can think of lots of ways to describe the concept, but most of them
seem rather verbose and awkward compared to "a list of words", "a
dictionary whose keys are words", etc.

When I talk about an iterable, I say "iterable". Based on my recent readings of the style guide PEPs I would write something like:

"""Foo-ify some words.

Arguments:
words -- an iterable of words

"""

Just remember that types don't matter (until you get down to the C, really), just the methods associated with an object.

Have fun and happy coding!
 
J

Jon Clements

Let's say I have a function which takes a list of words. I might write
the docstring for it something like:

def foo(words):
"Foo-ify words (which must be a list)"

What if I want words to be the more general case of something you can
iterate over? How do people talk about that in docstrings? Do you say
"something which can be iterated over to yield words", "an iterable over
words", or what?

I can think of lots of ways to describe the concept, but most of them
seem rather verbose and awkward compared to "a list of words", "a
dictionary whose keys are words", etc.

I would just write the function signature as (very similar to how itertools does it):

def func(iterable, ..):
pass

IMHO that documents itself.

If you need explicit, look at the itertools documentation.

hth

Jon.
 
S

Steven D'Aprano

I refer you to your subject line:

"How do you refer to an iterator in docs?"

In documentation, I refer to an iterator as an iterator, just as I would
refer to a list as a list, a dict as a dict, or a string as a string.

You may also find these useful:

sequence
something that obeys the sequence protocol, e.g. a list or a tuple

iterator
something which obeys the iterator protocol

iterable
something that can be iterated over, such as an iterator or a sequence



The sequence protocol is that the object should be indexed by consecutive
integers 0, 1, 2, ... and will raise IndexError when the index is past
the end of the sequence.

The iterator protocol is a little more complicated. To be a true iterator:

1) iter(obj) should return obj;

2) it should have a __next__ method (formerly: next without the
underscores) which takes no arguments and returns a value;

3) the __next__ method should raise StopIteration once the iterator is
exhausted.
 
R

Roy Smith

Steven D'Aprano said:
I refer you to your subject line:

"How do you refer to an iterator in docs?"

In documentation, I refer to an iterator as an iterator, just as I would
refer to a list as a list, a dict as a dict, or a string as a string.

Except that "list of foos" and "sequence of foos" make sense from a
grammar standpoint, but "iterator of foos" does not. Or maybe it does?
 
J

Jacob MacDonald

Except that "list of foos" and "sequence of foos" make sense from a
grammar standpoint, but "iterator of foos" does not. Or maybe it does?

Unless you're writing the docstring for end users, I think you should be fine using Python words. After all, this is Python :)
 
S

Steven D'Aprano

Except that "list of foos" and "sequence of foos" make sense from a
grammar standpoint, but "iterator of foos" does not. Or maybe it does?

Why wouldn't it make sense?
 
R

Roy Smith

Steven D'Aprano said:
Why wouldn't it make sense?

Because an iterator isn't a container. I don't know, maybe it does make
sense, but my first impression is that it sounds wrong.

A basket of apples is a basket which contains apples, in the same way a
list contains foos. But an iterator doesn't contain anything. You
wouldn't say, "a spigot of water", because the spigot isn't a container
holding the water. It is simply a mechanism for delivering the water in
a controlled way.
 
S

Steve Howell

Because an iterator isn't a container.  I don't know, maybe it does make
sense, but my first impression is that it sounds wrong.

A basket of apples is a basket which contains apples, in the same way a
list contains foos.  But an iterator doesn't contain anything.  You
wouldn't say, "a spigot of water", because the spigot isn't a container
holding the water.  It is simply a mechanism for delivering the water in
a controlled way.

If you don't want to imply a false sense of containment, then you
could say "iterator over foos" as opposed to "iterator of foos."
 
S

Steven D'Aprano

Because an iterator isn't a container. I don't know, maybe it does make
sense, but my first impression is that it sounds wrong.


Containers in Python are defined via the iteration protocol: an object is
a container if you can say "item in container", and that works for
iterators:
True

Although it must be said that since membership testing consumes the item,
perhaps it would have been better not to support it for iterators. But
membership testing should work for anything that supports iteration, so
either way you will surprise somebody.

A basket of apples is a basket which contains apples, in the same way a
list contains foos. But an iterator doesn't contain anything.

That's arguable. You are assuming an implementation detail. An iterator
may be a thin wrapper around some other sort of container, so in the
sense it may contain objects. It may also support rewinding (although
that is an extension to the normal iterator protocol, it is not
*forbidden*). Not all iterators are lazy producers of data.

And even those that are, in some philosophical sense they do contain the
value you care about. Some lazy iterator primes() which calculates the
prime numbers lazily may not *actually* contain the infinite list of
prime numbers, but in some sense every prime number is held by that
iterator in potentia, just waiting to be retrieved.

You
wouldn't say, "a spigot of water", because the spigot isn't a container
holding the water. It is simply a mechanism for delivering the water in
a controlled way.

Iterators are not simply the mechanism for delivering items. The iterator
*protocol* is the mechanism, iterator *objects* are objects.
 
S

Steven D'Aprano

A basket of apples is a basket which contains apples, in the same way a
list contains foos. But an iterator doesn't contain anything. You
wouldn't say, "a spigot of water", because the spigot isn't a container
holding the water. It is simply a mechanism for delivering the water in
a controlled way.


A better analogy would be a trickle, stream or torrent of water.

In English, "a foo of bar" does not necessarily imply containment, e.g. a
circle of friends, a conspiracy of silence, a flood of refugees, a tissue
of lies.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top