RE: [Python-Dev] PEP 276 (simple iterator for ints)
Andrew Koenig writes:
I happened to look at PEP 276 and was struck by the thought that PEP 276 is really an implementation of the well-known set-theoretic construction of the natural numbers that defines each natural number as the set of all smaller ones. In other words, it defines 0 as the empty set, 1 as the set whose only element is 0, 2 as the set whose elements are 0 and 1, and so on.
Interesting. I suppose that could be added as an extra argument against those who claim that [0,1,2,3,4,5] is *NOT* the sequence of integers "obviously" associated with the number 6. As for me, even before I started using Python I had already become convinced of that. PEP 276 is worth a second look. In fact, it's trivial to implement, and what it REALLY needs is a champion to bring it up with the BDFL (and others). Seriously, folks, replacing every one of these: >>> for i in range(len(myList)): ... doSomethingWithIndexes(i) with this: >>> for i in len(myList): ... doSomethingWithIndexes(i) is simple and elegant. And while at first glance it seems like allowing iteration over ints would open up all kinds of subtle bugs, I find that the PEP does a good job of arguing that it doesn't. -- Michael Chermside This email may contain confidential or privileged information. If you believe you have received the message in error, please notify the sender and delete the message without copying or disclosing it.
Interesting. I suppose that could be added as an extra argument against those who claim that [0,1,2,3,4,5] is *NOT* the sequence of integers "obviously" associated with the number 6. As for me, even before I started using Python I had already become convinced of that.
PEP 276 is worth a second look. In fact, it's trivial to implement, and what it REALLY needs is a champion to bring it up with the BDFL (and others). [snip example] is simple and elegant. And while at first glance it seems like allowing iteration over ints would open up all kinds of subtle bugs, I find that the PEP does a good job of arguing that it doesn't.
While PEP 276 attempts to make easier the most common iteration over integers (half open, 0...n-1), PEP 284 takes care of general iteration over integers (a...b, for arbitrary integer a and b, incrementing or decrementing as necessary). In this case, does practicality (usable for more integer iteration scenarios) outweigh the purity (integer fields/list indices)? - Josiah
"Chermside, Michael" <mchermside@ingdirect.com>:
>>> for i in len(myList): ... doSomethingWithIndexes(i)
is simple and elegant.
IMO it would be clearer, and equally elegant, to write this as something like for i in indices(myList): ... which is easily accomplished with the aid of a suitable definition for indices(). No language changes needed. I suspect most people other than number theorists would find the concept of a set of integers being contained in another integer quite wierd. Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+
Greg Ewing wrote:
"Chermside, Michael" <mchermside@ingdirect.com>:
for i in len(myList): ... doSomethingWithIndexes(i)
is simple and elegant.
IMO it would be clearer, and equally elegant, to write this as something like
for i in indices(myList): ...
which is easily accomplished with the aid of a suitable definition for indices(). No language changes needed.
And I believe most of those use cases are better covered by enumerate() anyway. Interesting that in the course of this discussion I've gone from 'nice idea' to 'no way!' Cheers, Nick. -- Nick Coghlan | Brisbane, Australia Email: ncoghlan@email.com | Mobile: +61 409 573 268
On Thursday 2004-07-01 03:17, Greg Ewing wrote:
I suspect most people other than number theorists would find the concept of a set of integers being contained in another integer quite wierd.
<pedant type="mathematician"> Actually, most number theorists would too. It's only set theorists to whom that seems like a natural definition. And the first (so far as I know) attempt to define the natural numbers set-theoretically did it quite differently: Gottlob Frege proposed to define n as the set of all sets of size n. Unfortunately, Frege's version of set theory famously didn't work (it was demolished by Russell's paradox) and his construction doesn't work in ZF set theory, which is what most set theorists use nowadays. In any case, saying that (e.g.) 3 is a member of 17 is generally regarded as an implementation detail. Mathematicians understand the different between interface and implementation just about as well as software people. (Which is to say: some understand it very well, and others don't.) By the by, I don't think it's true that sets.Set(42) would, under PEP276, be the usual implementation of 42 in set theory. It would be a set whose elements are ordinary Python integers, which are not themselves sets. If you see what I mean. :-) </pedant> -- g
Gareth McCaughan <gmccaughan@synaptics-uk.com> writes:
By the by, I don't think it's true that sets.Set(42) would, under PEP276, be the usual implementation of 42 in set theory. It would be a set whose elements are ordinary Python integers, which are not themselves sets. If you see what I mean. :-)
And that's what confused me most of all about Andy's assertion. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
IMO it would be clearer, and equally elegant, to write this as something like
for i in indices(myList): ...
which is easily accomplished with the aid of a suitable definition for indices(). No language changes needed.
I think that for i in myList.keys(): would be even better, because it allow the same usage for dict and list. Of course that wouldn't generalize to other sequences that support len. Incidentally, I've always liked Algol 68's loop syntax, which if I remember right is something like this: [ for <id> ] [ from <expr> ] [ to <expr> ] [ by <expr> ] [ while <expr> ] do <suite> od So one would write for i to n do ... od or even for i from 0 while <whatever> do ... od which would loop while <whatever> is true and keep count of the iterations.
Andrew Koenig wrote:
IMO it would be clearer, and equally elegant, to write this as something like
for i in indices(myList): ... I think that
for i in myList.keys():
would be even better, because it allow the same usage for dict and list. Of course that wouldn't generalize to other sequences that support len.
Wouldn't be better then that indices returns the keys for a dictionary instead? It would then support all these sequences. Maybe an index is not the good term to generalize, but I don't think key is really better, particularly since I would expect the use of a dictionary to be more rare. Maybe another function, let's say accesses, could be used for these rare cases, adding no overhead for common cases of indices: for key in accesses(myDict): pass for index in accesses(myList): pass But since iterating through a dictionary means to iterate through the keys, while it means to iterate through the elements for a list, would that be really uniform to support generalization with dictionaries? Is it useful? Regards, Nicolas
Nicolas Fleury wrote:
Andrew Koenig wrote:
IMO it would be clearer, and equally elegant, to write this as something like
for i in indices(myList): ...
I think that
for i in myList.keys():
would be even better, because it allow the same usage for dict and list. Of course that wouldn't generalize to other sequences that support len.
Wouldn't be better then that indices returns the keys for a dictionary instead? It would then support all these sequences. Maybe an index is not the good term to generalize, but I don't think key is really better, particularly since I would expect the use of a dictionary to be more rare.
Maybe another function, let's say accesses, could be used for these rare cases, adding no overhead for common cases of indices: for key in accesses(myDict): pass for index in accesses(myList): pass
I'm not sure this kind of generalization is correct at all - list elements are sorted, but dict's doesn't. Also accesses(myDict) might be misunderstood as accesses(myDict.keys()) which is incorrect in general (because keys() not guaranteed to return keys every time in same order). -- Best regards, Michael Dubner (dubnerm@mindless.com) Brainbench MVP/HTML+JavaScript (http://www.brainbench.com) PS: Sorry for my English
Quoting "Michael P. Dubner" <dubnerm-news@mail.ru>:
I'm not sure this kind of generalization is correct at all - list elements are sorted, but dict's doesn't. Also accesses(myDict) might be misunderstood as accesses(myDict.keys()) which is incorrect in general (because keys() not guaranteed to return keys every time in same order).
One question I have is just what the use case is where one wants to iterate over the indices of a list, but _don't_ want to look at the values. I can't think of a time where I've iterated over indices, without then having a container[index] written somewhere inside the loop. And for that use case, we can now use: for index, item in enumerate(container): pass I suppose a case where we're getting a more complicated slice than just the value corresponding to an index would qualify. But how many of these uses would also require more than just a simple sequential iteration over the indices? Regards, Nick. -- Nick Coghlan Brisbane, Australia
participants (10)
-
Andrew Koenig
-
Chermside, Michael
-
David Abrahams
-
Gareth McCaughan
-
Greg Ewing
-
Josiah Carlson
-
Michael P. Dubner
-
Nick Coghlan
-
Nick Coghlan
-
Nicolas Fleury