python for loop

L

Lie

No, there won't be any bizarro-talk. There is no argument: the zeroeth
item comes zeroeth, the first item comes first, and so on. The index
for the very zeroeth thing in a list is 0, so to get the zeroeth item
you use s[0]. While to get the first item you use s[1]. It's very
intuitive, isn't it?

Robot 1: I won zeroeth place at the contest, honey!
Robot 2: Congratulations!  I knew you could do it.

That should be Robot 0 and Robot 1.
 
H

Hrvoje Niksic

Carl Banks said:
This is unforgiveable, not only changing the indexing semantics of
Python (because a user would have NO CLUE that something underlying
has been changed, and thus it should never be done), but also for
the needless abuse of exec.

Then I guess you'd fire Guido, too -- from socket.py:

class _socketobject(object):
[...]
_s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
"%s.__doc__ = _realsocket.%s.__doc__\n")
for _m in _socketmethods:
exec _s % (_m, _m, _m, _m)
del _m, _s
 
S

Steven D'Aprano

Beyond being part of a conventionally-ordered set of keys, what can an
ordinality of zero actually mean? (That's a sincere question.)

In set theory, you start by defining the integers like this:

0 is the cardinality (size) of the empty set, the set with nothing in it.

1 is the cardinality of the set of empty sets, that is, the set
containing nothing but the empty set.

2 is the cardinality of the set of the empty set plus the set of empty
sets.

3 is the cardinality of the set containing the empty set, plus the set of
empty sets, plus the set of (the empty set plus the set of empty sets).

And so forth, to infinity and beyond.

Or to put it another way:


0 = len( {} )
1 = len( {{}} )
2 = len( {{}, {{}}} )
3 = len( {{}, {{}}, {{}, {{}}} )
etc.

For non-infinite sets, you can treat ordinal numbers and cardinal numbers
as more or less identical. So an ordinality of zero just means the number
of elements of something that doesn't exist.

How that relates to whether indexing should start at one or zero, I have
no idea.

Oh, and speaking of... I'm shocked, SHOCKED I say, that nobody has given
that quote about the compromise of 0.5.
 
S

Steven D'Aprano

There is a major clash between the names of ordinals in human languages
and zero-based counting. In human languages, the Nth-ordinal item comes
in position N. You can keep that useful convention with zero-based
counting by inventing the ugly word "zeroth", but that just leads to
bizarro-talk like "the zeroeth item comes first, the first item comes
second, and so on".

No, there won't be any bizarro-talk. There is no argument: the zeroeth
item comes zeroeth, the first item comes first, and so on. The index for
the very zeroeth thing in a list is 0, so to get the zeroeth item you
use s[0]. While to get the first item you use s[1]. It's very intuitive,
isn't it?

No, because "first", "second", "third" etc. have existed in the English
language for hundreds of years and everybody knows them. "Zeroeth" was
probably invented a few decades ago, and is known by maybe 1% of the
English-speaking population.

Given the list [a, b, c], if you ask even a C programmer *in English*
"what's the first item?", they will almost invariably answer a rather
than b.
 
C

Carl Banks

Despite being thoroughly acclimatised to zero-based indexing and having no
wish to change it, I'm starting to see the OP's point.

Many of the arguments presented in this thread in favour of zero-based
indexing have rather been arguments for half-open intervals, which I don't
think are in dispute. We all want these to be true:

foo[:n] is the first n items of the sequence foo
foo[:n] + foo[n:] == foo
len(foo[n:m]) == m-n
(foo[n:n]) is an empty sequence
etc.

and they are true with 0-based indexing if we exclude the last number, or
equally with 1-based indexing if we exclude the first.

Unless I'm missing something, wouldn't that mean:

range(0,10) -> [1,2,3,4,5,6,7,8,9,10]

Even though it's theoretically just another way to line up the open
interval, as practical matter it's going to be a lot more confusing.
Of course you could exclude the last number with one-based indexing
also, but that would be confusing too, since you would have to use
something like range(1,len(x)+1) to iterate over the items of x.

Given that, I'm going to disagree that a half-open interval is
desirable in the case of one-based indexing.

Furthermore, I know of no languages that use both one-based indexing
and half-open intervals. Do you know of any?

Beyond being part of a conventionally-ordered set of keys, what can an
ordinality of zero actually mean? (That's a sincere question.)

I think people were being facetious. To me the first item in the list
is x[0]--ordinal does not match cardinal. However, I don't use
ordinals much when talking about list items; I'll say item 2, not
third item.


Carl Banks
 
A

Aaron Brady

On Apr 1, 7:06 pm, Steven D'Aprano
No, there won't be any bizarro-talk. There is no argument: the zeroeth
item comes zeroeth, the first item comes first, and so on. The index for
the very zeroeth thing in a list is 0, so to get the zeroeth item you
use s[0]. While to get the first item you use s[1]. It's very intuitive,
isn't it?

No, because "first", "second", "third" etc. have existed in the English
language for hundreds of years and everybody knows them. "Zeroeth" was
probably invented a few decades ago, and is known by maybe 1% of the
English-speaking population.

Given the list [a, b, c], if you ask even a C programmer *in English*
"what's the first item?", they will almost invariably answer a rather
than b.

However, if you ask him/er, "What is the item that is 0 items from the
start of the list?", what will s/he say?
 
A

Arnaud Delobelle

Carl said:
On Apr 1, 2:32 pm, Arnaud Delobelle <[email protected]> wrote:

Check the date on the line above (and the PS in that post).
If I were your boss and you ever pulled something like this, your ass
would be so fired.

This is unforgiveable, not only changing the indexing semantics of
Python (because a user would have NO CLUE that something underlying
has been changed, and thus it should never be done), but also for the
needless abuse of exec.

Gotcha ;)
 
C

Carl Banks

Carl Banks said:
This is unforgiveable, not only changing the indexing semantics of
Python (because a user would have NO CLUE that something underlying
has been changed, and thus it should never be done), but also for
the needless abuse of exec.

Then I guess you'd fire Guido, too -- from socket.py:

class _socketobject(object):
    [...]
    _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
          "%s.__doc__ = _realsocket.%s.__doc__\n")
    for _m in _socketmethods:
        exec _s % (_m, _m, _m, _m)
    del _m, _s

Damn straight I would, recklessly using exec like he owns the language
or something.


Carl Bansk
 
J

John O'Hagan

[snip erudite definition of cardinality]
For non-infinite sets, you can treat ordinal numbers and cardinal numbers
as more or less identical. So an ordinality of zero just means the number
of elements of something that doesn't exist.

This is the bit I don't get - I had thought of ordinality as something
attached to each item - ['a','b','c'] has a cardinality of 3, and elements of
ordinality 1, 2 and 3 (first,second, third) respectively. So it's possible to
have a cardinality of zero (an empty sequence does) but only "something that
doesn't exist" can have an ordinality of zero; as soon as there is an item,
its ordinality is 1. Shoot me down, please!
How that relates to whether indexing should start at one or zero, I have
no idea.

Only insofar as the "weirdness" of indexing being out of step with
ordinality/cardinality matters, i.e. not that much. :)

John
 
A

Arnaud Delobelle

Steven said:
In set theory, you start by defining the integers like this:

0 is the cardinality (size) of the empty set, the set with nothing in it.

1 is the cardinality of the set of empty sets, that is, the set
containing nothing but the empty set.

2 is the cardinality of the set of the empty set plus the set of empty
sets.

3 is the cardinality of the set containing the empty set, plus the set of
empty sets, plus the set of (the empty set plus the set of empty sets).

And so forth, to infinity and beyond.

Or to put it another way:


0 = len( {} )
1 = len( {{}} )
2 = len( {{}, {{}}} )
3 = len( {{}, {{}}, {{}, {{}}} )

FWIW this is the way I learnt it AFAIK:

Ordinals
=======

0 *is* the empty set
1 *is* the the the singleton composed of the empty set, i.e. {0}
2 *is* the set {0, 1}
3 *is* the set {0, 1, 2}
....
n + 1 := n U {n}

It's nice because:
* the interval [0, n) is just the number n
* n < m iff n is a subset of m iff n is a member of m

Cardinals
=========

A cardinal is an equivalence class under the equivalence relation S ~
S' iff there is a bijection between S and S'. Obviously, finite
cardinals contain only one ordinal so finite cardinals can be
identified with their ordinal representative.
 
G

Gabriel Genellina

something i don't think has been mentioned much - if you're using
"range()" in your python code then you're almost always doing it wrong.

i just grepped lepl and i use range 20 times in 9600 lines of code. out
of those, all but 3 are in "quick and dirty" tests or experimental code,
not in the main library itself (which is 6300 lines).

(1) where i need to access two adjacent members of a list, and which has
a
comment in the code explaining why it is not an error (in other words, i
was so unhappy with my code i needed to leave a note explaining why it
was
like that)

From your description I guess this "range" usage could have been avoided,
using enumerate instead. A silly example:

for i,elem in enumerate(some_list):
if i>0:
prev = some_list[i-1]
print (elem+prev)/2

instead of:

for i in range(1, len(some_list)):
elem = some_list
prev = some_list[i-1]
print ...
(2) a use irrelevant to this discussion because i do not use the value to
an index an array.

(3) in the rather complex implementation of a circular buffer.

I can't tell, but perhaps enumerate() could have been used here too?
so in a small/moderate size library of 6000 lines (including blanks and
comments, but excluding tests and exploratory code) the only time i have
used range with array indices i was either unhappy with the code, or
implementing a complex data structure.

Maybe the ratio is even less than that.
 
L

Lou Pecora

Steven D'Aprano said:
So an ordinality of zero just means the number
of elements of something that doesn't exist.


You do realize that will give most people headaches. :)
 
T

Tim Wintle

In set theory, you start by defining the integers like this:
0 = len( {} )
1 = len( {{}} )
2 = len( {{}, {{}}} )
3 = len( {{}, {{}}, {{}, {{}}} )
etc.
not quite len() - surely you mean something like "any object along with
an algebra in which the left hand side is equivalent to the right in the
algebra of set theory?" - at least for ordinals.

The cardinal is then (for finite numbers) the length of that.


Or, in a pythonic sense (taking 0,1,2,... to be variable names):
0 = set()
1 = set(0)
2 = set(1,0)
3 = set(2,1,0)
3 = set(3,2,1,0)
etc.

How that relates to whether indexing should start at one or zero, I
have
no idea.

so in this sense, range(n) is actually very close to the ordinal value
of 0 (except for being a list and not a set - but it's not in 3.0)

i.e. range(n) returns something very similar to the ordinal "n", and
with cardinality n. That seems very sensible to me.

Oh, and speaking of... I'm shocked, SHOCKED I say, that nobody has
given that quote about the compromise of 0.5.
"God made the integers, all else is the work of man" - Leopold Kronecker

....holding myself back from complaining about integer division in Py3K
when the philosophical question of whether irrational numbers even exist
(in a physics sense) is fairly open.

Tim W
 
L

Lou Pecora

I think people were being facetious. To me the first item in the list
is x[0]--ordinal does not match cardinal. However, I don't use
ordinals much when talking about list items; I'll say item 2, not
third item.


Well, it's been said in many forms in this thread, but maybe this
version will click with some. Thinking of ordinals as specifying
position by order and cardinals as counting the number of steps from a
specified place to an item you just have to realize that 0 and 1 based
indexing have decided to use *different* definitions for the
conglomerate symbols A or A(i):

1 based indexing (ordinality):
A is the ith item in the ordered list (1st, 2nd, etc. - no need for
0th as an ordinal)

0 based indexing (cardinality):
A is the item i steps from the beginning of the list.

I know most of what's been said is all around the above, I just thought
explict statements might help. Both are prefectly reasonable and
consistent definitions. Confusion only comes when you try to force the
defintion of one of them on the other and then say it's illogical or not
natural. Both are natural.

Of course, in some languages like C an array name, say A, points to the
first item in memory of the array which is assumed to be structured
sequentially. Then A[0] is the first item at the address A or since we
are using cardinality (0 based indexing) it's the item 0 steps from the
beginning. A[1] is the item at address A+1, i.e. 1 step from the
address A, the array beginning.

I suspect that was a very practical choice for C since it's a systems
language and down at that level you're flipping bit, bytes, addresses,
etc. But a practical consequence was that there was very little +1 or
-1 arithmetic necessary to manipulate the array elements. That carried
over into other languages and their design. People have already pointed
out the nice features of such in Python where A[n:n] is an empty list,
A[:n]+A[n:]=A, etc.

Now, I'm not a systems/computer guy. Just a scientist who does a lot of
number crunching. But I have found out that even in that case you end
of traversing lists, tuples, etc. a lot. Slicing and dicing them. And
you quickly come to appreciate the 0 based approach to indexing and soon
don't miss the Fortran 1-based indexing.
 
E

Emile van Sebille

Lou said:
Confusion only comes when you try to force the
defintion of one of them on the other and then say it's illogical or not
natural. Both are natural.

Consider the French 'Premiere etage' vs the American 'First Floor'

Emile
 
T

Tim Wintle

Consider the French 'Premiere etage' vs the American 'First Floor'

or even in the same language - "first floor" in English (UK) is very
different from "first floor" in English (US).
 
A

Aaron Brady

or even in the same language - "first floor" in English (UK) is very
different from "first floor" in English (US).

Did I tell you guys that 'natural' has 38 definitions at
dictionary.com?
 
L

Lie

On Apr 1, 7:06 pm, Steven D'Aprano
No, there won't be any bizarro-talk. There is no argument: the zeroeth
item comes zeroeth, the first item comes first, and so on. The index for
the very zeroeth thing in a list is 0, so to get the zeroeth item you
use s[0]. While to get the first item you use s[1]. It's very intuitive,
isn't it?

No, because "first", "second", "third" etc. have existed in the English
language for hundreds of years and everybody knows them. "Zeroeth" was
probably invented a few decades ago, and is known by maybe 1% of the
English-speaking population.

Given the list [a, b, c], if you ask even a C programmer *in English*
"what's the first item?", they will almost invariably answer a rather
than b.

Alternatively:
"One friend of mine half-seriously advanced the following thesis: We
should count from zero. But "first" is, etymologically, a diminution
of "foremost", and (as TomStambaugh says) should mean "0th" when we
count from 0. And "second" is from the Latin "secundus", meaning
"following", so it should mean "1th" when we count from 0. Obviously
the ordinals from "third" onwards get their names from the numbers.
So... we need a new word for "2th". He proposed "twifth". Thus: first,
second, twifth, third, fourth, ..."
-- GarethMcCaughan (from http://c2.com/cgi/wiki?ZeroAndOneBasedIndexes
)

No zeroeth, "twifth"
 
M

MRAB

Lie wrote:
[snip]
Alternatively:
"One friend of mine half-seriously advanced the following thesis: We
should count from zero. But "first" is, etymologically, a diminution
of "foremost", and (as TomStambaugh says) should mean "0th" when we
count from 0. And "second" is from the Latin "secundus", meaning
"following", so it should mean "1th" when we count from 0. Obviously
the ordinals from "third" onwards get their names from the numbers.
So... we need a new word for "2th". He proposed "twifth". Thus: first,
second, twifth, third, fourth, ..."
I propose "twoth" (sounds like "tooth"). :)
 

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

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top