python for loop

L

Lada Kugis

I'm coming from fortran and c background so I'm certainly biased by
them. But if you could explain one thing to me:

in fortran for example:
for i=1,n
goes from 1,2,3,4,...,n

in python for example:
for i in range(1,n)
goes from 1,2,3,4,...,n-1
(that is, it goes from 1 up to, but not including n)

Why is that so ? What were the reasons for that "not including" part ?
It troubles me greatly, and I cannot see it's advantages over the
"standard" "up to and including" n.

Best regards
Lada
 
C

Chris Rebert

I'm coming from fortran and c background so I'm certainly biased by
them. But if you could explain one thing to me:

in fortran for example:
for i=1,n
goes from 1,2,3,4,...,n

in python for example:
for i in range(1,n)
goes from 1,2,3,4,...,n-1
(that is, it goes from 1 up to, but not including n)

Why is that so ? What were the reasons for that "not including" part ?
It troubles me greatly, and I cannot see it's advantages over the
"standard" "up to and including" n.

Because it's extremely handy when the list variable is a list index:

my_list = [1,2,3,4]
for i in range(len(my_list)):
#i goes from 0 to len(my_list)-1, which is all the indices of the list
print my_list

Of course, this is a toy example which would be better written `for i
in my_list:`, but you get the point.

Cheers,
Chris
 
L

Lada Kugis

I'm coming from fortran and c background so I'm certainly biased by
them. But if you could explain one thing to me:

in fortran for example:
for i=1,n
goes from 1,2,3,4,...,n

And of course, lapsus calami, this is wrong and it should go like:

do 1 i=1,n
.... goes from ...
 
L

Lada Kugis

Lada Kugis said:
in python for example:
for i in range(1,n)
goes from 1,2,3,4,...,n-1
(that is, it goes from 1 up to, but not including n)

Also, ?range(n)? counts from 0 to n-1.
Why is that so ?

The answer is in the documentation for ?range?:

For example, range(4) returns [0, 1, 2, 3]. The end point is
omitted! These are exactly the valid indices for a list of 4
elements.

Yes, but why didn't they start indexing from 1 then, like fortran for
example ?
It would solve for [1,2,3,4] length of list (just returns the last
indice, in this case 4), "up to and including" problem, ...

Lada
 
C

Chris Rebert

Lada Kugis said:
in python for example:
for i in range(1,n)
goes from 1,2,3,4,...,n-1
(that is, it goes from 1 up to, but not including n)

Also, ?range(n)? counts from 0 to n-1.
Why is that so ?

The answer is in the documentation for ?range?:

   For example, range(4) returns [0, 1, 2, 3]. The end point is
   omitted! These are exactly the valid indices for a list of 4
   elements.

Yes, but why didn't they start indexing from 1 then, like fortran for
example ?
It would solve for [1,2,3,4] length of list (just returns the last
indice, in this case 4), "up to and including" problem, ...

Might I suggest you read Dijkstra's famous justification for 0-numbering:
http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF

Among other things, it has the nice property that:
len(some_list[n:m]) == m-n

Cheers,
Chris
 
G

Gary Herron

Lada said:
I'm coming from fortran and c background so I'm certainly biased by
them. But if you could explain one thing to me:

in fortran for example:
for i=1,n
goes from 1,2,3,4,...,n

in python for example:
for i in range(1,n)
goes from 1,2,3,4,...,n-1
(that is, it goes from 1 up to, but not including n)

Why is that so ? What were the reasons for that "not including" part ?
It troubles me greatly, and I cannot see it's advantages over the
"standard" "up to and including" n.

Best regards
Lada
This debate has been around for decades, in both mathematics and
programming.

Should a loop through n things use indices
1, 2, ..., n
or
0, 1, ..., n-1 ?

Fortran tends to go with the former (1-based indices) , while modern
languages usually go with the latter (0-based indices). (And just for
the record, your range(1,n) seems to be trying to coerce Python from
0-based to 1-based.)

The arguments for each are many, but are often centered around the
prevalence of the proverbial off-by-one error. Here's a nice
explanation of the off-by-one error:
http://en.wikipedia.org/wiki/Off-by-one_error
Google can provide many more.


My personal view is that 0-based loops/indices is *far* more natural,
and the 1-based loops/indices are a *huge* source of off-by-one errors.
But I'm sure others will argue over that point.

Gary Herron
 
S

Steven D'Aprano

I'm coming from fortran and c background so I'm certainly biased by
them. But if you could explain one thing to me:

in fortran for example:
for i=1,n
goes from 1,2,3,4,...,n

in python for example:
for i in range(1,n)
goes from 1,2,3,4,...,n-1
(that is, it goes from 1 up to, but not including n)

Why is that so ? What were the reasons for that "not including" part ?
It troubles me greatly, and I cannot see it's advantages over the
"standard" "up to and including" n.


Why Python (and other languages) count from zero instead of one, and
why half-open intervals are better than closed intervals:

http://www.johndcook.com/blog/2008/06/26/why-computer-scientists-count-from-zero/
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html
 
L

Lada Kugis

This debate has been around for decades, in both mathematics and
programming.

Should a loop through n things use indices
1, 2, ..., n
or
0, 1, ..., n-1 ?

Fortran tends to go with the former (1-based indices) , while modern
languages usually go with the latter (0-based indices). (And just for
the record, your range(1,n) seems to be trying to coerce Python from
0-based to 1-based.)

Oh, don't mind those. I just bumped them off the top of my head for
purpose of comparison.
The arguments for each are many, but are often centered around the
prevalence of the proverbial off-by-one error. Here's a nice
explanation of the off-by-one error:
http://en.wikipedia.org/wiki/Off-by-one_error
Google can provide many more.


My personal view is that 0-based loops/indices is *far* more natural,
and the 1-based loops/indices are a *huge* source of off-by-one errors.
But I'm sure others will argue over that point.

Yes, that's it. I won't argue over it, since I can't change it, but 1
is still more natural to me (it is "the real world" way). The above
pros seem to me to be very little compared to the cons of the ... and
the (m-n) point Chris was trying to explain doesn't seem that relevant
to me.
I always thought since python is trying so hard to be as intuitive as
it can get it would be the other way (you have 1 apple, you start
counting from 1 ...

but then again, I have training of an engineer, not as an CS, so we
probably have a completely different view of looking at things.

Thank you for the explanation Gary.

Ciao,
Lada
 
L

Lada Kugis

Lada said:
I'm coming from fortran and *********** c ***********
background so I'm certainly biased by
them. But if you could explain one thing to me:

but this is exactly the same behaviour as the standard way of doing things
in c!

int a[5];
for (i = 0; i < 5; ++i) {
a = 0;
}

were you being honest about the c background?!


:)
Yes, I usually avoid lyes. They are hard to remember.

In C you can do it either way, I usually use the one starting from 1
and with "=", since that way it corresponds to my paper data.
Why it troubles me so much: for example, I'm doing the FEM analysis of
a simple ... uhmm, not sure how you say this, stick or beam or girder

node 1 ******* node 2 ******* node 3

I have n=3 nodes and n-1 elements. The matrix will have 3 rank.
The indexes in the matrix correspond to the nodes, and so on.
(this is just an elementary example, but you probably understand)

If I try this in py, it goes for i in range(0,3) then it gets all
moved by one. If I go (1,4) then it ...

Lada
 
L

Lada Kugis

Why Python (and other languages) count from zero instead of one, and
why half-open intervals are better than closed intervals:

http://www.johndcook.com/blog/2008/06/26/why-computer-scientists-count-from-zero/
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html

steven, thanks for answering,

yes, i saw the second one a little time ago (someone else posted it as
well in really cute handwriting version :) and the first time just
now, but the examples which both of them give don't seem to me to be
that relevant, e.g. the pros don't overcome the cons.

imho, although both sides (mathematical vs engineer) adress some
points, none of them give the final decisive argument.
i understand the math. point of view, but from the practical side it
is not good. it goes nicely into his tidy theory of everything, but
practical and intuitive it is not. as i said, being an engineer, i
tend towards the other side, so this is biased opinion (nobody can be
unbiased) but from a practical side it seems unpractical for
engineering problems (and to me, the purpose of computers is to help
humans to build a better world, not to prove theories - theories are
useless if they don't help us in reality. so we should try to adapt
computing to real world, not our world to computers).

but i just read somewhere that guido who wrote python is a mathem. so
that probably had to do with the decision.

nevertheless, thank you for the links.
you have a nice group here, i always am nicely suprised how people
tend to be helpful

nice regards
lada
 
C

Chris Rebert

Lada said:
I'm coming from fortran and   *********** c ***********
background so I'm certainly biased by
them. But if you could explain one thing to me:

but this is exactly the same behaviour as the standard way of doing things
in c!

int a[5];
for (i = 0; i < 5; ++i) {
 a = 0;
}

were you being honest about the c background?!


:)
Yes, I usually avoid lyes. They are hard to remember.

In C you can do it either way


Sort of, but it's *really* not idiomatic. You'd have to declare the
arrays to be one longer than they actually are so that array[N] is a
valid index. And then you'd end up not using the true first element of
the array. Not to mention most library functions use 0-numbering, so
you'd have to work around that as well.

So, it can be done, but you're going against the grain of the language.

Cheers,
Chris
 
W

woooee

Counting from zero through n-1 is used because it is the memory offset
and not any kind of counter. Simplified, if you are iterating through
a list, using a for loop or anything else, the first element/number is
at memory offset zero because it is at the beginning. And if this is
a list of 4 byte integers, the offset for the second element is 1*4
bytes, etc. This idea, that somehow the first element of a list is
the zero element is a fairly recent abnormality AFAIK. It perhaps
comes from assumptions by people who are not familiar with what
happens inside of a programming language, assuming incorrectly, that
the (programming) world was created in their own image, and so
programming languages were generated in the way that they think they
were. This is a bad assumption for any programmer. Instead one
should get in the habit of saying, in general as well as in this
specific case, "This doesn't make sense. I wonder how __I__ screwed
this up." Hopefully this will be helpful advice. Taking the attitude
that you have screwed up yet again will get to the heart of the
problem, and save many hours of frustration wondering why "this
language/computer doesn't do what it is supposed to do".
 
L

Lada Kugis

Sort of, but it's *really* not idiomatic. You'd have to declare the
arrays to be one longer than they actually are so that array[N] is a
valid index. And then you'd end up not using the true first element of
the array. Not to mention most library functions use 0-numbering, so
you'd have to work around that as well.

So, it can be done, but you're going against the grain of the language.

I use fortran libraries, so that is not a problem for me. I only make
the change once, while transferring the elements ... uhmm, make that
twice.
I wrote in my other post, 0 is weird to me, I have model of solution
on paper ... if I keep 0 then all comes out different. And while
comparing, I always get them mixed up. That's why I always try to
adapt it to the paper situation.

Lada
 
L

Lada Kugis

Counting from zero through n-1 is used because it is the memory offset
and not any kind of counter. Simplified, if you are iterating through
a list, using a for loop or anything else, the first element/number is
at memory offset zero because it is at the beginning. And if this is
a list of 4 byte integers, the offset for the second element is 1*4
bytes, etc. This idea, that somehow the first element of a list is
the zero element is a fairly recent abnormality AFAIK. It perhaps
comes from assumptions by people who are not familiar with what
happens inside of a programming language, assuming incorrectly, that

I thoughts high level languages were created primarily so we don't
have to think about what happens inside a programming language, memory
offsets and the like.
the (programming) world was created in their own image, and so
programming languages were generated in the way that they think they
were. This is a bad assumption for any programmer. Instead one
should get in the habit of saying, in general as well as in this
specific case, "This doesn't make sense. I wonder how __I__ screwed
this up." Hopefully this will be helpful advice. Taking the attitude
that you have screwed up yet again will get to the heart of the
problem, and save many hours of frustration wondering why "this
language/computer doesn't do what it is supposed to do".

Why do we try to create languages that are intuitive to humans, then ?

Lada
 
L

Lada Kugis

Two opportunities to forget to lie about how big your array is :)

It is rank 3, meaning a33 is the last element. I don't see how any
alternative can be simpler than that.
Ever considered adapting the paper situation to it?

And start mentally rewriting all the books on the subject - you must
be joking! The given one was a trivial example, used models are not
nearly that simple.
You might find
that the results come out more naturally.

.... the force in the third node, at b(2) ?


Alternatively, idiomatic
Python seems to have a strong tendency not to need subscripting,
since you spend most of your time iterating through lists instead.

Yes, but you still need to give conditions, and for that you use
manually indexes. You need, for example, give force value at node 3,
which would come out as b(2).
Yes, there is a lot of iterating, but indexing is still important.

This loses some importance when you make a GUI, so you don't handle
all this manually, but I don't make (or know how to) those, so I'm
stuck with manual work ;-(

Still, tomorrow is a brand new day (rainy probably though).
I'm going to sleep, see you tomorrow.
Lada
 
B

Brendon Wickham

Since when should a machine (that's what a computer is after all), be
forced to contort itself into something that is capable of reflecting
the laws of physical matter?

Better perhaps to look at it from another angle - it's
counter-intuitive to think that the digital should mirror the
analogue. The digital can *virtualise* the real world, but it doesn't
do that by *working like* the real world.

It's not theory, it's actually what it is.


2009/4/1 Lada Kugis said:
Sort of, but it's *really* not idiomatic. You'd have to declare the
arrays to be one longer than they actually are so that array[N] is a
valid index. And then you'd end up not using the true first element of
the array. Not to mention most library functions use 0-numbering, so
you'd have to work around that as well.

So, it can be done, but you're going against the grain of the language.

I use fortran libraries, so that is not a problem for me. I only make
the change once, while transferring the elements ... uhmm, make that
twice.
I wrote in my other post, 0 is weird to me, I have model of solution
on paper ... if I keep 0 then all comes out different. And while
comparing, I always get them mixed up. That's why I always try to
adapt it to the paper situation.

Lada

Cheers,
Chris
 
S

Steven D'Aprano

Why do we try to create languages that are intuitive to humans, then ?

Because of the foolish hope that sufficiently easy syntax will make
excellent programmers out of average people.

Programming is not intuitive to humans. *Counting* isn't intuitive to
humans -- children need to learn how to count.

Very few things really are intuitive. Somebody once said that the only
truly intuitive thing is the nipple, but even with a broader definition
of intuitive, programming still isn't intuitive. There's nothing
intuitive about deleting a node from a red-black tree, or re-scaling a
floating point calculation to avoid overflow.

That's not to say that syntax doesn't matter. Poor syntax gets in the way
and makes it hard to read, comprehend and write code. But the aim of easy-
to-use syntax is for the syntax to get out of the way. Good syntax
doesn't turn a non-programmer into a programmer, but it lowers the
barrier to a non-programmer to learn how to program.
 
H

Hrvoje Niksic

Chris Rebert said:
Among other things, it has the nice property that:
len(some_list[n:m]) == m-n

And also that it is intuitive how to represent an empty slice
(foo[n:n]). When traversing over sublists, it's also a useful
property that foo[a:b] + foo[b:c] == foo.
 
C

Carl Banks

steven, thanks for answering,

yes, i saw the second one a little time ago (someone else posted it as
well in really cute handwriting version :) and the first time just
now, but the examples which both of them give don't seem to me to be
that relevant, e.g. the pros don't overcome the cons.

imho, although both sides (mathematical vs engineer) adress some
points, none of them give the final decisive argument.
i understand the math. point of view, but from the practical side it
is not good. it goes nicely into his tidy theory of everything, but
practical and intuitive it is not. as i said, being an engineer, i
tend towards the other side,


Lada,

I am also an engineer, and I can tell your idea of intuitive is not
universal, even among engineers. I certainly do not lean toward one-
based indexing.

From a programming standpoint--and remember Python is a programming
language--zero-based indexing eliminates the need for a whole lot of
extra +1s and -1s when indexing, slicing, and iterating, a lot more
than it causes, and that is worth the "cost". This might not be
apparent to you if you never tried seriously taking advantage of
indexing from zero, or if your programming experience is very narrow.
These both seem to be true for you, so you'll just have to take my
word for it.

I'm sorry that the zero-based indexing isn't the most natural for your
field. There are some things about Python that aren't the natural
choice for me, too.

I would, however, highly recommend that you avoid the ridiculous
pseudo-one-based indexing trick you pulled when interfacing C to
Fortran. Python is zero-based, and you are going to have a much
better experience if you don't fight it. I assure you that it is
really not that hard to cope with indices being off by one from what
you have written down. Really. I have to interface two languages,
one of which indexes from one, the other from zero, and it really is
no problem.


Carl Banks
 
D

Diez B. Roggisch

Lada said:
steven, thanks for answering,

yes, i saw the second one a little time ago (someone else posted it as
well in really cute handwriting version :) and the first time just
now, but the examples which both of them give don't seem to me to be
that relevant, e.g. the pros don't overcome the cons.

imho, although both sides (mathematical vs engineer) adress some
points, none of them give the final decisive argument.
i understand the math. point of view, but from the practical side it
is not good. it goes nicely into his tidy theory of everything, but
practical and intuitive it is not.

You keep throwing around the concept of "intuition" as if it were
something that existis in a globally fixed frame of reference. It is not.

From [1]:

"""
Klein found that under time pressure, high stakes, and changing
parameters, experts used their base of experience to identify similar
situations and intuitively choose feasible solutions.
"""

In other words: your gained *knowledge* (including mathematical
know-how) determines what's intuitive - to *you*.

So all arguing about intuition is rather irrelevant - to me, zero-based
counting is intuitive, and it is so with the same right as you prefer
one-based.

OTOH zero-based counting has technical reasons that also reduces the
amount of leaky abstraction problems [2], as it models the underlying
reality of memory locations + indexing.

Diez



[1] http://en.wikipedia.org/wiki/Intuition_(knowledge)
[2] http://www.joelonsoftware.com/articles/LeakyAbstractions.html
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top