msg229979 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-25 03:43 |
The existing documentation is confusing.
— improve wording as follows
enumerate(sequence, start=0)
Returns pairings of index into sequence[link to glossary.html#term-sequence] with the object at that index in the sequence.
— wording as found in v.2.7.5
enumerate(sequence, start=0)
Return an enumerate object. sequence must be a sequence, an iterator, or some other object which supports iteration. The next() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over sequence:
|
msg229984 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2014-10-25 05:14 |
The existing documentation is technically correct, while your replacement leaves some things out, such as the fact that enumerate accepts an iteratable and returns an iterator that is specifically a special 'enumerate object'. (A sequence is an iteratable, but not all iterables sequences, and enumerate specifically does *not* return a list of pairs, and it is important to know that).
Can you explain what it is you find confusing about the existing documentation? The examples should go a long way toward clarifying the text for those not familiar enough with the precisely correct terms it uses.
|
msg229986 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-25 06:11 |
I don't want to argue. Ask a 12-year old and their English teacher, "Does the second sentence qualify as gobbledygook even if it is technically correct and complete and not verbose?"
To be constructive and take on what has been said, an iteration on improving the wording:
-- improve wording as follows:
enumerate(iteratable, start=0)
Accepts an iteratable[typo for iterable?] and returns an iterator, a special case 'enumerate object'. The method iterator.next() returns a tuple which pairs an index counter with the object at the index in iterable.
>>> led = ['red', 'green', 'blue']
led = ['red', 'green', 'blue']
>>> iter = enumerate(led)
iter = enumerate(led)
>>> iter.next()
iter.next()
(0, 'red')
>>> iter.next()
iter.next()
(1, 'green')
>>> iter.next()
iter.next()
(2, 'blue')
# While enumerate does not return a list of pairs,
# it is easy to collect the pairs and construct a list as follows
>>> list(enumerate(led))
list(enumerate(led))
[(0, 'red'), (1, 'green'), (2, 'blue')]
|
msg229988 - (view) |
Author: Ethan Furman (ethan.furman) * |
Date: 2014-10-25 08:20 |
rdm was not asking for an argument, he was asking for a more detailed explanation of what was confusing. Your initial response lacked courtesy and respect, and is not appreciated.
The rest of your reply was much better. Next time, please skip the non-constructive portion.
|
msg229989 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-25 08:53 |
Understood. I felt the problem was self evident with "sequence must be a sequence".
|
msg229991 - (view) |
Author: Georg Brandl (georg.brandl) * |
Date: 2014-10-25 09:54 |
> I felt the problem was self evident with "sequence must be a sequence".
The two words are not used in the same sense: the first names the argument of the function, the second is one of several possible object types you can pass for that argument.
|
msg229992 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-25 10:10 |
> "sequence must be a sequence"
The subtle minutiae of aficionados necessary to interpret the meaning of those two words in their distinct relation is opaque to a new comer and doesn’t serve the widest possible audience usefully to get the job done quick. The second placed sense has a range of possibility narrower than iterable as has been said, all sequences are iterables but not all iterables sequences.
|
msg229994 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-25 11:20 |
The first mention of iterator should link to 'glossary.html#term-iterator'.
There is a builtin iter() function. This may cause confusion in earlier suggested inline sample code.
-- Use the following inline sample code
-- in place of 'iter = enumerate(led)'to avoid confusion with iter() builtin:
led = ['red', 'green', 'blue']
iterator = enumerate(led)
try:
while True:
print iterator.next()
except StopIteration:
print 'End of iterator has been reached.'
|
msg230006 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2014-10-25 15:06 |
I think you misunderstand the purpose of the documentation you are suggesting modifying. It is a *reference guide*, and as such it needs to be technically precise and *must* correctly use the "jargon" of the language. Especially since it also functions as the reference guide for people who implement new versions of Python, and need to know what behavior of things like 'enumerate' they need to reproduce.
That said, we also prefer the reference docs to be clear and understandable to someone who is a relative beginner, as long as we don't lose precision in doing so. Thus the glossary and the glossary links, so yes it would be a good idea to add those.
I did indeed misspell iterable.
Your sentence is still incorrect...items returned by an iterator do not necessarily have an index (that is, you can't say myiterator[3] in the general case).
So, if I understand correctly, your difficulty was the confusion between the argument name *sequence* and the technical term ``sequence`` (referring to a Python object type). I agree that that makes things confusing. It would be better if the argument were named *iterable*, but we can't really change it at this point for backward compatibility reasons.
Maybe if we rearrange things a bit we can make it clearer. How about this:
Return an enumerate object which when iterated[link to glossary] yields a two-tuple for each element in *sequence*, each tuple consisting of the sequence number of the element (beginning with *start*, which defaults to 0) paired with the element itself. *sequence* must be a sequence, an iterator, or some other object which supports iteration.
That moves the distracting precise definition of *sequence* to the end, after you've already grasped what the function does. You will note that I've also dropped the reference to next; that is implicit in the mention of "when iterated", since it is an integral part of the iteration protocol. IMO it is a distraction to mention next in this context. It confuses the beginner and isn't needed by the expert.
|
msg230012 - (view) |
Author: Ethan Furman (ethan.furman) * |
Date: 2014-10-25 20:03 |
+1 for rdm's change.
|
msg230057 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-27 02:35 |
Reference by the guide to next() should stay for the same reason in re.compile() a regular expression object is returned and the two methods are mentioned, match() and search(). They are useful to know in that context in as much as next() is useful to know here. IMO.
|
msg230062 - (view) |
Author: Georg Brandl (georg.brandl) * |
Date: 2014-10-27 07:52 |
next() is quite unlike match() and search(), as you almost never use next() on iterators directly. Rather, the iterator is iterated by constructs like a for loop or a comprehension, or another function that consumes it (list, map, ...)
|
msg230067 - (view) |
Author: Van Ly (vy0123) * |
Date: 2014-10-27 10:37 |
While next() is rarely used directly on iterators, as you say, it may help to remind the experienced reader of the mechanical characteristic in essence which a new reader on first approach uses to construct a mental model.
|
msg230071 - (view) |
Author: Ethan Furman (ethan.furman) * |
Date: 2014-10-27 13:29 |
I do not think 'next' is needed in this context. Unlike 'match' and 'search', 'next' is a function that can be used with any iterator and mentioning it here is unnecessary.
|
msg230086 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2014-10-27 18:50 |
That would not be consistent with the rest of the docs. Consider, for example, that the full documetation of dictionary views (https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects), which are iterables in much the same way that the enumerate object is, does not mention next. The glossary link to iterable will lead the reader to the discussion of next, which is a fundamental Python concept and does not need to be repeated. In my opinion, of course, others may disagree.
|
msg230127 - (view) |
Author: Georg Brandl (georg.brandl) * |
Date: 2014-10-28 08:23 |
rdm: your suggestion sounds good. Note that the argument name is "iterable" in Py3.
|
msg230409 - (view) |
Author: Terry J. Reedy (terry.reedy) * |
Date: 2014-10-31 23:00 |
The first argument of enumerate is 'iterable' in the 2.7 docstring also.
"enumerate(iterable[, start]) -> iterator for index, value of iterable
Return an enumerate object. iterable must be another object that supportsniteration. The enumerate object yields pairs containing a count (from\nstart, which defaults to zero) and a value yielded by the iterable argument. enumerate is useful for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."
We should update at least that part of the doc entry.
|
msg230418 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2014-11-01 01:04 |
The "sequence" parameter name is an unfortunate hold-over from olden times were many things that accepted iterables were marked as taking sequences.
This was fixed in Python 3, but it can't be changed in Py2.7 because the parameter name is exposed as a keyword argument:
>>> list(enumerate(sequence='abc', start=2))
[(2, 'a'), (3, 'b'), (4, 'c')]
The rest docs for Python 2.7 read just fine, "Return an enumerate object. sequence must be a sequence, an iterator, or some other object which supports iteration." I think that is sufficient to clarify any confusion caused by the unfortunate choice of keyword argument name.
|
msg230423 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2014-11-01 01:58 |
We have a suggestion for a wording improvement (that does not change the sentence to which you refer) that has been accepted as better than the existing wording by a couple of committers. This improvement is actually independent of what the variable is named. The 2.7 docstring should also be fixed to show the actual argument name, IMO.
|
msg230427 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2014-11-01 03:28 |
Can you attach a proposed patch and I will make a decision.
FWIW, I'm very happy with the current documentation at https://docs.python.org/2.7/library/functions.html#enumerate Between the text, example, and pure python equivalent, it does a great job communicating what enumerate is supposed to do.
Proposed improvements to the docstring should match the main documentation as much as possible.
|
msg230575 - (view) |
Author: Tshepang Lekhonkhobe (tshepang) * |
Date: 2014-11-04 04:56 |
@raymond
Why do you say that 'sequence' is a keyword?
>>> enumerate()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Required argument 'sequence' (pos 1) not found
That means that 'sequence' can be changed to 'iterable' without worrying about backwards compatibility.
|
msg230578 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2014-11-04 05:22 |
static PyObject *
> Why do you say that 'sequence' is a keyword?
It is a keyword argument to enumerate(). Here's the relevant section of code:
enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
enumobject *en;
PyObject *seq = NULL;
PyObject *start = NULL;
static char *kwlist[] = {"sequence", "start", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
&seq, &start))
return NULL
|
msg230590 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2014-11-04 08:10 |
Specifically, this works (in 2.7):
>>> enumerate(sequence=myvar)
Changing sequence to iterable would break any code that was written like the above.
|
msg230661 - (view) |
Author: Tshepang Lekhonkhobe (tshepang) * |
Date: 2014-11-05 06:22 |
Oh, I see now. The documentation doesn't make it clear.
Anyways, what were the advantages of making it a keyword, instead of
just a positional argument?
|
msg230664 - (view) |
Author: Georg Brandl (georg.brandl) * |
Date: 2014-11-05 07:13 |
Missing keyword argument support is not the norm, it's the exception that is only due to implementation details in C code. Eventually, we'd like every C function to support keyword arguments.
Converting everything is tedious work, though, and still makes things slower (that may become less of an issue eventually with Clinic), so only select functions are converted.
Functions are good candidates for keyword argument support when they have parameters that are best passed as keywords, such as
enumerate(x, start=5)
which makes it immediately clear what the second parameter does.
|
msg230666 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2014-11-05 08:29 |
I'm sorry but I do not like the proposed patch at all. The wording is awkward "which when iterated" and has weird terminology "the sequence number".
The OP's concern about the *sequence* versus *iterable* parameter name has been addressed (it is part of the 2.7 API and is unchangeable).
I see no need for revising the text which already discusses "sequence or some other object that supports iterable", that has clear examples, and that has pure python equivalent code. The existing wording has worked well for most people for the better part of a decade.
|
msg244688 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2015-06-02 19:33 |
Per Raymond's last message, closing this as rejected.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:09 | admin | set | github: 66914 |
2015-06-02 19:33:54 | r.david.murray | set | assignee: rhettinger -> docs@python messages:
+ msg244688 stage: needs patch -> resolved |
2014-11-05 08:29:23 | rhettinger | set | status: open -> closed resolution: rejected messages:
+ msg230666
|
2014-11-05 07:13:18 | georg.brandl | set | messages:
+ msg230664 |
2014-11-05 06:22:48 | tshepang | set | messages:
+ msg230661 |
2014-11-04 11:49:18 | Arfrever | set | nosy:
+ Arfrever
|
2014-11-04 08:10:37 | r.david.murray | set | messages:
+ msg230590 |
2014-11-04 05:22:06 | rhettinger | set | messages:
+ msg230578 |
2014-11-04 04:56:17 | tshepang | set | nosy:
+ tshepang messages:
+ msg230575
|
2014-11-02 18:05:17 | r.david.murray | set | files:
+ enumerate_doc-3.4.patch |
2014-11-02 18:04:51 | r.david.murray | set | files:
+ enumerate-doc.2.7.patch keywords:
+ patch |
2014-11-01 03:28:40 | rhettinger | set | messages:
+ msg230427 |
2014-11-01 01:58:05 | r.david.murray | set | status: closed -> open resolution: rejected -> (no value) messages:
+ msg230423
versions:
+ Python 3.4, Python 3.5 |
2014-11-01 01:04:22 | rhettinger | set | status: open -> closed
assignee: docs@python -> rhettinger versions:
- Python 3.4, Python 3.5 nosy:
+ rhettinger
messages:
+ msg230418 resolution: rejected |
2014-10-31 23:00:11 | terry.reedy | set | versions:
- Python 3.6 nosy:
+ terry.reedy
messages:
+ msg230409
stage: needs patch |
2014-10-28 08:23:38 | georg.brandl | set | messages:
+ msg230127 |
2014-10-27 18:50:45 | r.david.murray | set | messages:
+ msg230086 |
2014-10-27 13:29:49 | ethan.furman | set | messages:
+ msg230071 |
2014-10-27 10:37:29 | vy0123 | set | messages:
+ msg230067 |
2014-10-27 07:52:24 | georg.brandl | set | nosy:
+ georg.brandl messages:
+ msg230062
|
2014-10-27 02:35:15 | vy0123 | set | messages:
+ msg230057 |
2014-10-25 20:03:28 | ethan.furman | set | messages:
+ msg230012 |
2014-10-25 19:41:26 | georg.brandl | set | nosy:
- georg.brandl
|
2014-10-25 15:06:58 | r.david.murray | set | messages:
+ msg230006 |
2014-10-25 11:20:00 | vy0123 | set | messages:
+ msg229994 |
2014-10-25 10:10:23 | vy0123 | set | messages:
+ msg229992 |
2014-10-25 09:54:16 | georg.brandl | set | nosy:
+ georg.brandl messages:
+ msg229991
|
2014-10-25 08:53:18 | vy0123 | set | messages:
+ msg229989 |
2014-10-25 08:20:29 | ethan.furman | set | nosy:
+ ethan.furman messages:
+ msg229988
|
2014-10-25 06:11:31 | vy0123 | set | messages:
+ msg229986 |
2014-10-25 05:14:20 | r.david.murray | set | nosy:
+ r.david.murray messages:
+ msg229984
|
2014-10-25 03:56:25 | ezio.melotti | set | nosy:
+ ezio.melotti
versions:
+ Python 3.4, Python 3.6, - Python 3.3 |
2014-10-25 03:43:56 | vy0123 | create | |