Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is using range() in for loops really Pythonic?

0 views
Skip to first unread message

John Salerno

unread,
May 10, 2008, 10:19:54 PM5/10/08
to
I know it's popular and very handy, but I'm curious if there are purists
out there who think that using something like:

for x in range(10):
#do something 10 times

is unPythonic. The reason I ask is because the structure of the for loop
seems to be for iterating through a sequence. It seems somewhat
artificial to use the for loop to do something a certain number of
times, like above.

Anyone out there refuse to use it this way, or is it just impossible to
avoid?

Matt Nordhoff

unread,
May 10, 2008, 10:34:59 PM5/10/08
to pytho...@python.org

Well, you should use "xrange(10)" instead of "range(10)". While range()
returns a list of every single number, xrange() returns an iterable
object that only generates them on-demand, so xrange(1) and
xrange(sys.maxint) will use the same amount of RAM.

(Not that it matters when it's only 10 items, of course.)

Other than that, "for i in xrange(10)" is a standard Python idiom, even
though it is a bit weird.
--

7stud

unread,
May 10, 2008, 10:37:05 PM5/10/08
to
On May 10, 8:19 pm, John Salerno <johnj...@NOSPAMgmail.com> wrote:
> I know it's popular and very handy, but I'm curious if there are purists
> out there who think that using something like:
>
> for x in range(10):
>     #do something 10 times
>
> is unPythonic. The reason I ask is because the structure of the for loop
> seems to be for iterating through a sequence. It seems somewhat
> artificial to use the for loop to do something a certain number of
> times, like above.
>

x = range(10)
print x

--output:--
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Paddy

unread,
May 11, 2008, 1:19:10 AM5/11/08
to

Hi John,
If you have an object that is both indexable and iterable, then
visiting every member by first generating an index then indexing the
object is un-pythonic. You should just iterate over the object.

Like most rules, things can get fuzzy around the edges: if you have n
objects to be visited each index at a time, then the more functional
approach would be to izip all the objects and iterate over the result.
Another way would be to iterate over the the enumeration of one object
and use the index created to index the other n-1 objects.

In all such situations you need to remember that things such as code
clarity, and speed, might make the final decision for you.


In the following examples then the first is what I would use, izip. If
I needed an index then I'd prefer the last, which combines izip and
enumerate:

PythonWin 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit
(Intel)] on win32.
Portions Copyright 1994-2006 Mark Hammond - see 'Help/About PythonWin'
for further copyright information.

>>> obj1 = 'CSM'
>>> obj2 = 'aue'
>>> obj3 = 'tmn'
>>> from itertools import izip
>>> for x,y,z in izip(obj1, obj2, obj3):
... print x,y,z
...
C a t
S u m
M e n
>>> for i,x in enumerate(obj1):
... print x, obj2[i], obj3[i]
...
C a t
S u m
M e n
>>> for i in range(len(obj1)):
... print obj1[i], obj2[i], obj3[i]
...
C a t
S u m
M e n
>>> for i,(x,y,z) in enumerate(izip(obj1, obj2, obj3)):
... print i, x, y, z
...
0 C a t
1 S u m
2 M e n
>>>


- Paddy.

Paul Rubin

unread,
May 11, 2008, 1:38:55 AM5/11/08
to
John Salerno <john...@NOSPAMgmail.com> writes:
> for x in range(10):
> #do something 10 times
>
> is unPythonic. The reason I ask is because the structure of the for loop
> seems to be for iterating through a sequence. It seems somewhat
> artificial to use the for loop to do something a certain number of
> times, like above.

It is pretty natural in imperative-style code. The one thing I'd do
differently is use xrange instead of range, to avoid creating a
10-element list in memory before starting the loop.

XLiIV

unread,
May 11, 2008, 2:58:49 AM5/11/08
to

The range() function returns a list and list is a sequence, isn't?

casti...@gmail.com

unread,
May 11, 2008, 4:09:21 AM5/11/08
to
On May 11, 12:38 am, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:

If you give extras to memory, can Python live?

John Salerno

unread,
May 11, 2008, 4:11:49 PM5/11/08
to

Ok, I think most people are misunderstanding my question a little. I
probably should have said xrange instead of range, but the point of my
question remains the same:

Should a for loop be used simply to do something X number of times, or
should it strictly be used to step through an iterable object for the
purpose of processing the items in that object?

Terry Reedy

unread,
May 11, 2008, 4:14:29 PM5/11/08
to pytho...@python.org

"XLiIV" <Tymoteusz...@gmail.com> wrote in message
news:41078222-aec0-4e8b...@m73g2000hsh.googlegroups.com...

yes, for loops iterate thru any iterable

John Salerno

unread,
May 11, 2008, 4:16:53 PM5/11/08
to
XLiIV wrote:

> The range() function returns a list and list is a sequence, isn't?

I think you're missing the point. To me, there seems to be a fundamental
difference between these two things:

---

people = ['Sam', 'Bob', 'Fred']

for name in people:
print name

---

AND

---

num = 33

for x in xrange(10):
print num += 1

---

To me, the first example is a pure use of the for loop. You are
iterating through an object and *using* the items you are stepping through.

The second example, however, is simply doing something 10 times, and
what it's doing has nothing to do with 'x' or xrange. So it seems like
an abuse of the for loop.

Arnaud Delobelle

unread,
May 11, 2008, 4:28:15 PM5/11/08
to
John Salerno <john...@gmailNOSPAM.com> writes:

It makes me feel slightly uncomfortable too, but AFAIK there is no
better way in Python. What I sometimes do is make the for loop bind
its variable to something useful instead of an unused counter.
Contrived example:

# Print 'hello' 10 times; x is not used
for x in xrange(10):
print 'hello'

# By changing what is iterated over, no unused variable:
from itertools import repeat
for msg in repeat('hello', 10):
print msg

--
Arnaud

Ben Finney

unread,
May 11, 2008, 6:44:19 PM5/11/08
to
John Salerno <john...@gmailNOSPAM.com> writes:

> num = 33
>
> for x in xrange(10):
> print num += 1

Which is better done by 'num += 10'.

Can you come up with an example that isn't trivially replaced with
clearer code? That might make it clearer what your concern is.

> The [above] example [...] is simply doing something 10 times, and


> what it's doing has nothing to do with 'x' or xrange. So it seems
> like an abuse of the for loop.

In such cases, the name 'dummy' is conventionally bound to the items
from the iterator, for clarity of purpose::

for dummy in range(10):
# do stuff that makes no reference to 'dummy'

Also note that 'range' will return an iterator (not a list) in Python
3.0, and 'xrange' is removed since it's then obsolete
<URL:http://www.python.org/dev/peps/pep-3100/#built-in-namespace>.

--
\ “Isn’t it enough to see that a garden is beautiful without |
`\ having to believe that there are fairies at the bottom of it |
_o__) too?” —Douglas Adams |
Ben Finney

Yves Dorfsman

unread,
May 11, 2008, 6:51:09 PM5/11/08
to
John Salerno wrote:
>
> To me, the first example is a pure use of the for loop. You are
> iterating through an object and *using* the items you are stepping through.
>
> The second example, however, is simply doing something 10 times, and
> what it's doing has nothing to do with 'x' or xrange. So it seems like
> an abuse of the for loop.

Well, I would say this:
myl = ['a', 'b', 'c', 'd']
for i in xrange(len(myl)):
print myl[i]

As you would see in other languages, is an abuse in python. But in you need
to iterate 5 times over something. Do you have a cleaner / python'er
alternative ?

Do you find the following cleaner:

x = 0
while x <= 4:
print x
x += 1

Yves.
http://www.SollerS.ca

Message has been deleted

Jonathsn Cronin

unread,
May 11, 2008, 8:43:08 PM5/11/08
to
On Sun, 11 May 2008 16:16:53 -0400, John Salerno wrote
(in message <48275446$0$11628$607e...@cv.net>):

I agree in principle; the first is iteration and the second is repetition.
In Python, the common idiom for a fixed number of repetitions is iterating
over a number range. This is true in most languages I am familiar with,
probably because fixed repetition, where you don't care about the "index"
value, is rarely used.

The only language I've used that does have fixed repetition is an (old)
dialect of lisp, and I'm not sure it even made it into Common Lisp.
Smalltalk and Ruby do have fixed repetition.

Using range may not be entirely elegant, but is pragmatic, and not, to me,
particularly ugly. In Python, unlike some languages, you don't have to
declare the x.

I think you could add it without too much change to the parsing.

for <expression>:
<block>

Seeing a ":" instead of "in" would mean a repetition statement which would
be interpreted as:
-- if <expression> evaluates to an integer, execute the block that number of
times.
-- If <expression> evaluates to an iterator, execute the block until the
iterator is exhausted.

Even if possible, I see this at best a minor improvement and more likely a
negative because the for keyword is now overloaded. (see "static" in C/Java.)
You could add a new keyword but the benefit here is much to small to justify
the trouble.

Jonathan

Carl Banks

unread,
May 11, 2008, 9:52:48 PM5/11/08
to
On May 11, 6:44 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:

> In such cases, the name 'dummy' is conventionally bound to the items
> from the iterator, for clarity of purpose::
>
> for dummy in range(10):
> # do stuff that makes no reference to 'dummy'

Is this documented? I've never heard of this convention. It's not
PEP 8, and I've never seen consistent usage of any name. I'd be
interested in knowing where you read that this was a convention, or in
what subcommunities it's a convention in.

I think dummy is a terrible name to use for this, since in no other
usage I can think of does the word "dummy" suggest something isn't
used. In fact, quite the opposite. For example, the dummy_threads
module is most definitely used; the word dummy means that it's
stripped down. Based on that, your usage of the symbol dummy above
would suggest to me that it's a value used in lieu of something else
(such as a calculated value).

In mathematics, a dummy argument another name for the independent
variable of a function (or more accurately, the symbol used to
represent it), which also doesn't match your usage.

If a value isn't used, then I think the most clear name for it is
"unused".


Carl Banks

Ivan Illarionov

unread,
May 11, 2008, 10:33:41 PM5/11/08
to

I agree with Carl. This group is the only place I've heard about this
convension and it looks terrible IMO. Even if a value is not used, the
variable still has a meaning: it is a counter, or an index.

I know about the other convention: "for i in xrange" or "for i in range".
Wikipedia agrees with me:
http://en.wikipedia.org/wiki/For_loop
Examples in wikipedia article use either "i" or "counter".

It is established convention in almost every programming language and its
origins are in mathematics (matrix indices).

Google search for "for dummy in range" (with quotes) gives 164 results
While "for dummy in range" gives 146 000 results. Almost thousand times
more.

So, "i" is more conventional and as such is more readable.

-- Ivan

Message has been deleted

Ben Finney

unread,
May 11, 2008, 11:41:25 PM5/11/08
to
Carl Banks <pavlove...@gmail.com> writes:

> On May 11, 6:44 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
> wrote:
> > In such cases, the name 'dummy' is conventionally bound to the items
> > from the iterator, for clarity of purpose::
> >
> > for dummy in range(10):
> > # do stuff that makes no reference to 'dummy'
>
> Is this documented?

It's not a documented standard, to my knowledge.

> I've never heard of this convention. It's not PEP 8, and I've never
> seen consistent usage of any name. I'd be interested in knowing
> where you read that this was a convention, or in what subcommunities
> it's a convention in.

It has been in this forum that the use of the name '_' for "don't care
about the value" was deprecated, since that name is already overloaded
with other meanings.

> I think dummy is a terrible name to use for this, since in no other
> usage I can think of does the word "dummy" suggest something isn't
> used.

I think it's far superior to '_'. I'd be just as happy with any other
name that explicitly distinguishes itself for this purpose.

> If a value isn't used, then I think the most clear name for it is
> "unused".

Sounds good to me. Now we merely need to convince the world.

--
\ “Software patents provide one more means of controlling access |
`\ to information. They are the tool of choice for the internet |
_o__) highwayman.” —Anthony Taylor |
Ben Finney

John Salerno

unread,
May 11, 2008, 11:46:42 PM5/11/08
to
Ben Finney wrote:

> John Salerno <john...@gmailNOSPAM.com> writes:
>
>> num = 33
>>
>> for x in xrange(10):
>> print num += 1
>
> Which is better done by 'num += 10'.
>
> Can you come up with an example that isn't trivially replaced with
> clearer code? That might make it clearer what your concern is.

::sigh:: No, unfortunately I don't have a strong enough grasp of Python
to give a really in-depth example. I understand what you're asking
though. Perhaps people don't use this idiom as much as I think they do,
so to give a trivial example to support my point isn't helpful.

As far as I know, though, I think this is used often enough, so I
thought I'd just ask if there are purists out there who don't like this
use of the loop and feel it's an abuse of the syntax.

Carl Banks

unread,
May 12, 2008, 12:32:13 AM5/12/08
to
On May 11, 11:41 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:

> Carl Banks <pavlovevide...@gmail.com> writes:
> > On May 11, 6:44 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
> > wrote:
> > > In such cases, the name 'dummy' is conventionally bound to the items
> > > from the iterator, for clarity of purpose::
>
> > > for dummy in range(10):
> > > # do stuff that makes no reference to 'dummy'
>
> > Is this documented?
>
> It's not a documented standard, to my knowledge.
>
> > I've never heard of this convention. It's not PEP 8, and I've never
> > seen consistent usage of any name. I'd be interested in knowing
> > where you read that this was a convention, or in what subcommunities
> > it's a convention in.
>
> It has been in this forum that the use of the name '_' for "don't care
> about the value" was deprecated, since that name is already overloaded
> with other meanings.

That doesn't follow at all from what you wrote: no one in this thread
had even mentioned the usage of "_" for unused values--how did you
expect us to know you were talking about something no one brought up?

So it seems that usage of "dummy" is not a convention, and avoidance
of "_" is not really a convention except on this group.


> > I think dummy is a terrible name to use for this, since in no other
> > usage I can think of does the word "dummy" suggest something isn't
> > used.
>
> I think it's far superior to '_'. I'd be just as happy with any other
> name that explicitly distinguishes itself for this purpose.
>
> > If a value isn't used, then I think the most clear name for it is
> > "unused".
>
> Sounds good to me. Now we merely need to convince the world.

I'm happy to discourage the world from using "_" for this purpose;
ambivalent whether you even need to use a specific name.


Carl Banks

Ivan Illarionov

unread,
May 12, 2008, 1:18:37 AM5/12/08
to
>> In such cases, the name 'dummy' is conventionally bound to the items
>> from the iterator, for clarity of purpose
[..]

> If a value isn't used, then I think the most clear name for it is
> "unused".
[...]

Maybe my brain works differently, but I find both "dummy" and "unused"
are extremely confusing names for loop counters. The loop begins to look
like it doesn't iterate at all if its counter is dummy or unused.

If it *counts* it is *used* and it's *not* dummy.

Why reinvent the wheel when "a common identifier naming convention is for
the loop counter to use the variable names i, j and k (and so on if
needed)" (from Wikipedia http://en.wikipedia.org/wiki/Loop_counter )

-- Ivan

Ben Finney

unread,
May 12, 2008, 1:20:29 AM5/12/08
to
John Salerno <john...@NOSPAMgmail.com> writes:

> Ben Finney wrote:
>
> > John Salerno <john...@gmailNOSPAM.com> writes:
> >
> >> num = 33
> >>
> >> for x in xrange(10):
> >> print num += 1
> >
> > Which is better done by 'num += 10'.
> >
> > Can you come up with an example that isn't trivially replaced with
> > clearer code? That might make it clearer what your concern is.
>
> ::sigh:: No, unfortunately I don't have a strong enough grasp of
> Python to give a really in-depth example.

It need not be in-depth, merely illustrative of the problem being
addressed.

> I understand what you're asking though. Perhaps people don't use
> this idiom as much as I think they do, so to give a trivial example
> to support my point isn't helpful.

I think that the idiom

for unused in xrange(10):
# do stuff with no reference to 'unused'

is quite common. Is that what you're asking about?

> As far as I know, though, I think this is used often enough, so I
> thought I'd just ask if there are purists out there who don't like
> this use of the loop and feel it's an abuse of the syntax.

No, it seems quite a normal usage of the syntax and a good use of an
iterator.

With "do something N times", there must be *something* to keep track
of which iteration we're up to (or, equivalently, how many iterations
remain) at a given moment. A Python iterator seems a fine choice to
hold that information, and better than many alternatives.

--
\ "My house is on the median strip of a highway. You don't really |
`\ notice, except I have to leave the driveway doing 60 MPH." -- |
_o__) Steven Wright |
Ben Finney

Message has been deleted

Ben Finney

unread,
May 12, 2008, 2:24:23 AM5/12/08
to
Ivan Illarionov <ivan.il...@gmail.com> writes:

> >> In such cases, the name 'dummy' is conventionally bound to the items
> >> from the iterator, for clarity of purpose
> [..]
> > If a value isn't used, then I think the most clear name for it is
> > "unused".
> [...]
>
> Maybe my brain works differently, but I find both "dummy" and
> "unused" are extremely confusing names for loop counters. The loop
> begins to look like it doesn't iterate at all if its counter is
> dummy or unused.
>
> If it *counts* it is *used* and it's *not* dummy.

The value is unused by any of the code inside the block. For the
purposes of that block, it is a dummy value.

That something *else* (the iterator driving the 'for') is taking care
of knowing when the loop is finished is great. However, in the code
the programmer is writing, the loop counter is entirely unused.

> Why reinvent the wheel when "a common identifier naming convention
> is for the loop counter to use the variable names i, j and k (and so
> on if needed)" (from Wikipedia
> http://en.wikipedia.org/wiki/Loop_counter )

That is also regrettably common in Python code. It still suffers from
being unnecessarily ambiguous, since there are *also* plenty of loops
using 'i', 'j', etc. where the loop counter *is* used.

Differentiating these use cases by appropriate naming is, IMO, worth
the effort of choosing a meaningful name.

--
\ "Ignorance more frequently begets confidence than does |
`\ knowledge." —Charles Darwin, _The Descent of Man_, 1871 |
_o__) |
Ben Finney

Paddy

unread,
May 12, 2008, 2:27:23 AM5/12/08
to
On May 11, 9:28 pm, Arnaud Delobelle <arno...@googlemail.com> wrote:
Hi John, Arnaud;

> Contrived example:
>
> # Print 'hello' 10 times; x is not used
> for x in xrange(10):
> print 'hello'

I've used Fortran and C and so would tend to use either i,j,k as the
unused loop variable above, or, for clarity, call it something
descriptive like loop_count, if the loop body would be clearer.

I would also just use range for small, (especially small constant),
ranges.

>
> # By changing what is iterated over, no unused variable:
> from itertools import repeat
> for msg in repeat('hello', 10):
> print msg

I guess I would not go to the trouble of using itertools.repeat unless
it was simplifying/homogenising a larger expression - i.e if it was
part of some functional expression

I've never fealt the need for a separate repeat statement myself
either.

- Paddy.

P.S: I do understand that your examples are contrived. Just my
thoughts.

Ivan Illarionov

unread,
May 12, 2008, 2:56:47 AM5/12/08
to
On Mon, 12 May 2008 16:24:23 +1000, Ben Finney wrote:
[...]

> That is also regrettably common in Python code. It still suffers from
> being unnecessarily ambiguous, since there are *also* plenty of loops
> using 'i', 'j', etc. where the loop counter *is* used.
>
> Differentiating these use cases by appropriate naming is, IMO, worth the
> effort of choosing a meaningful name.

Even if the counter is not used inside the loop's body it's still in
control of the whole loop and, IMO, any special discriminating and non-
conventional name doesn't worth the added confusion.

-- Ivan

Roel Schroeven

unread,
May 12, 2008, 3:15:36 AM5/12/08
to
John Salerno schreef:

> Ben Finney wrote:
>
>> John Salerno <john...@gmailNOSPAM.com> writes:
>>
>>> num = 33
>>>
>>> for x in xrange(10):
>>> print num += 1
>> Which is better done by 'num += 10'.
>>
>> Can you come up with an example that isn't trivially replaced with
>> clearer code? That might make it clearer what your concern is.
>
> ::sigh:: No, unfortunately I don't have a strong enough grasp of Python
> to give a really in-depth example. I understand what you're asking
> though. Perhaps people don't use this idiom as much as I think they do,
> so to give a trivial example to support my point isn't helpful.

Perhaps a function to print some text a number of times:

def print_n(text, n):
for i in xrange(n):
print text

(Though I guess you can replace that with print '\n'.join(msg * n) )

--
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
-- Isaac Asimov

Roel Schroeven

Ben Finney

unread,
May 12, 2008, 3:40:06 AM5/12/08
to
Ivan Illarionov <ivan.il...@gmail.com> writes:

> On Mon, 12 May 2008 16:24:23 +1000, Ben Finney wrote:
> [...]
> > That is also regrettably common in Python code. It still suffers
> > from being unnecessarily ambiguous, since there are *also* plenty
> > of loops using 'i', 'j', etc. where the loop counter *is* used.
> >
> > Differentiating these use cases by appropriate naming is, IMO,
> > worth the effort of choosing a meaningful name.
>
> Even if the counter is not used inside the loop's body it's still in
> control of the whole loop

Not in Python it's not. The values that come out of the iterator
aren't "in control of the loop". The state for the loop is in the
*iterator*, not the values that come out.

Having access to the values that come from the iterator is usually
useful, but regardless of whether one uses them or not, they're *not*
controlling the loop, and it's confusing to imply that they are.

So, when not using the values that come from the controlling iterator,
it's good to make that explicit. If Python supported it, we might
prefer to use no name at all for something that isn't used, but the
'for' syntax doesn't allow that.

In the absence of supporting syntax, the next best thing is to choose
a name that *does* make it explicit that the values will not be used.

--
\ “All television is educational television. The question is: |
`\ what is it teaching?” —Nicholas Johnson |
_o__) |
Ben Finney

Ben Finney

unread,
May 12, 2008, 3:42:52 AM5/12/08
to
Paddy <padd...@googlemail.com> writes:

> I've used Fortran and C and so would tend to use either i,j,k as the
> unused loop variable above, or, for clarity, call it something
> descriptive like loop_count, if the loop body would be clearer.

The problem with all of these names is that they also have long
precedent as names of values that *will* be used inside the loop.

Because of the precedent of those names, choosing one of those names
doesn't make it clear to the reader that the value is never used; they
have no indication from you of that until they look over the code a
few times. It's implicit rather than explicit.

--
\ "As I bit into the nectarine, it had a crisp juiciness about it |
`\ that was very pleasurable - until I realized it wasn't a |
_o__) nectarine at all, but A HUMAN HEAD!!" -- Jack Handey |
Ben Finney

Ivan Illarionov

unread,
May 12, 2008, 6:04:17 AM5/12/08
to
>> On Mon, 12 May 2008 16:24:23 +1000, Ben Finney wrote: [...]
>> > That is also regrettably common in Python code. It still suffers from
>> > being unnecessarily ambiguous, since there are *also* plenty of loops
>> > using 'i', 'j', etc. where the loop counter *is* used.
>> >
>> > Differentiating these use cases by appropriate naming is, IMO, worth
>> > the effort of choosing a meaningful name.
>>
>> Even if the counter is not used inside the loop's body it's still in
>> control of the whole loop
>
> Not in Python it's not. The values that come out of the iterator aren't
> "in control of the loop". The state for the loop is in the *iterator*,
> not the values that come out.
>
> Having access to the values that come from the iterator is usually
> useful, but regardless of whether one uses them or not, they're *not*
> controlling the loop, and it's confusing to imply that they are.

I agree that "in control" was incorrect phrase.



> So, when not using the values that come from the controlling iterator,
> it's good to make that explicit. If Python supported it, we might prefer
> to use no name at all for something that isn't used, but the 'for'
> syntax doesn't allow that.
>
> In the absence of supporting syntax, the next best thing is to choose a
> name that *does* make it explicit that the values will not be used.

Name 'i' does not imply whether it's used inside the loop or not.
IMO it perfectly covers both cases.

It may have small advantage to "make it explicit that the values will not
be used", but names like "dummy", "unused", "ignored" or "junk" can be
confusing for some people and break the established conventions for
counter variable names (and these conventions are reasonable and are
taken from mathematics). "i" is still the best choice.

And let's agree to disagree. It's clear that we have different opinions
and it looks that this discussion is not going to change them.

-- Ivan

Grant Edwards

unread,
May 12, 2008, 10:34:48 AM5/12/08
to
On 2008-05-12, Ben Finney <bignose+h...@benfinney.id.au> wrote:

>> Maybe my brain works differently, but I find both "dummy" and
>> "unused" are extremely confusing names for loop counters. The loop
>> begins to look like it doesn't iterate at all if its counter is
>> dummy or unused.
>>
>> If it *counts* it is *used* and it's *not* dummy.
>
> The value is unused by any of the code inside the block. For the
> purposes of that block, it is a dummy value.

The value may be unused, but for me it's the name that matters,
not the value. The name might be in use by other code, and
the careless choice of a "dummy" name that's _supposed_ to be
unused has broken code precisely becuase the name was being
used (for something else). Requiring that the user pollute a
namespace with a useless name is a wart.

> That is also regrettably common in Python code. It still
> suffers from being unnecessarily ambiguous, since there are
> *also* plenty of loops using 'i', 'j', etc. where the loop
> counter *is* used.

Perhaps I'm the only one who's ever been stupid enough to
overwrite an index named "i" (that is being used) with another
index named "i" (that isn't being used)...


--
Grant Edwards grante Yow! All of life is a blur
at of Republicans and meat!
visi.com

Grant Edwards

unread,
May 12, 2008, 10:44:58 AM5/12/08
to
On 2008-05-12, Ben Finney <bignose+h...@benfinney.id.au> wrote:

I too, agree that requiring a name be bound to the values
coming out of the iterator seems "wrong".

> With "do something N times", there must be *something* to keep track
> of which iteration we're up to (or, equivalently, how many iterations
> remain) at a given moment. A Python iterator seems a fine choice to
> hold that information, and better than many alternatives.

An iterator like xrange() is an excellent choice. But, since
the iterator contains that information, why require that that
value be "exported" by the iterator and bound to an externally
visible name? In the case in question, the only thing you need
from the iterator is the StopIteration exception. To me,
exposing the internal state of the iterator and requiring that
the user bind a name to it each time through the loop feels
we're like driving a nail with a screwdriver.

--
Grant Edwards grante Yow! Was my SOY LOAF left
at out in th'RAIN? It tastes
visi.com REAL GOOD!!

Grant Edwards

unread,
May 12, 2008, 10:46:07 AM5/12/08
to
On 2008-05-12, Ben Finney <bignose+h...@benfinney.id.au> wrote:
> Paddy <padd...@googlemail.com> writes:
>
>> I've used Fortran and C and so would tend to use either i,j,k as the
>> unused loop variable above, or, for clarity, call it something
>> descriptive like loop_count, if the loop body would be clearer.
>
> The problem with all of these names is that they also have long
> precedent as names of values that *will* be used inside the loop.

I guess people who standardize on loop_count never nest loops. :)

> Because of the precedent of those names, choosing one of those
> names doesn't make it clear to the reader that the value is
> never used; they have no indication from you of that until
> they look over the code a few times. It's implicit rather than
> explicit.

And when somebody adds a nested loop things fall apart.

--
Grant Edwards grante Yow! BARBARA STANWYCK makes
at me nervous!!
visi.com

Paddy

unread,
May 12, 2008, 11:15:49 AM5/12/08
to
On May 12, 3:46 pm, Grant Edwards <gra...@visi.com> wrote:
> On 2008-05-12, Ben Finney <bignose+hates-s...@benfinney.id.au> wrote:

>
> > Paddy <paddy3...@googlemail.com> writes:
>
> >> I've used Fortran and C and so would tend to use either i,j,k as the
> >> unused loop variable above, or, for clarity, call it something
> >> descriptive like loop_count, if the loop body would be clearer.
>
> > The problem with all of these names is that they also have long
> > precedent as names of values that *will* be used inside the loop.
>
> I guess people who standardize on loop_count never nest loops. :)
>
> > Because of the precedent of those names, choosing one of those
> > names doesn't make it clear to the reader that the value is
> > never used; they have no indication from you of that until
> > they look over the code a few times. It's implicit rather than
> > explicit.
>
> And when somebody adds a nested loop things fall apart.
I don't have an example to hand. A lot of casses of repeat_X_times
inside a loop of repeat_Y_times would naturally be written as
repeat_Y*X_times.
Oh, wait a bit,
<oversimplified_example_alert>
for i in range(3):
print "Stay!"
for j in range(2):
print "Come over."
</oversimplified_example_alert>

Which could become:

for outer_stay_repetions in range(3):
print "Stay!"
for inner_come_over_repetions in range(2):
print "Come over."

But the second is daft. Nested repeats don't neccessarily pose a
problem to choosing meaningful names for repeat counters that are not
going to be referenced in the loop body, and most times i,j,k are fine
for used and un-used loop indices I find.

- Paddy
(Or were you just having a laugh ;-)

Carl Banks

unread,
May 12, 2008, 2:23:07 PM5/12/08
to
On May 12, 3:42 am, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:

> Because of the precedent of those names, choosing one of those names
> doesn't make it clear to the reader that the value is never used;


Why is it even necessary to document this? This is the thing that
baffles me the most about this thread.

Think about all the various aspect of a varibale:

* is it some common usage archetype
* value it represents
* scope
* (expected) type
* physical units of measure
* software package it belongs to
* whether it's used in the program or not
* scalar, structure, or array
* mutable or constant
* and so on

You cannot possibly document all of this pertinent information in the
name alone. A variable's name is a very limited resource: one can
only document a tiny number of things, so one must prioritize.

IMHO, whether a varibale is used or not has got to be one of the least
important things of all (in no small part because it's easily
discernable from nearby code). In fact, I'd say it's so irrelevant I
probably wouldn't have listed it if it wasn't the topic of discussion.

The first two items I listed are the most important to me. If a
variable fills the archetypal role of counter, then it ought to be
named like a counter; this usually trumps all other concerns. (Never
mind that the varibale here isn't really a counter, it still fills the
archetypal role of one, which is more important. The name of a
variable is for the reader's benefit.) So I would have to agree with
Ivan Illarionov.

Having said that, if you do think it's most important to document
whether something is used, I would suggest not using "_" (because it's
conflicts with gettext conventions) or "dummy" (because it's
misleading) for it.


Carl Banks

Ben Finney

unread,
May 12, 2008, 7:03:53 PM5/12/08
to
Carl Banks <pavlove...@gmail.com> writes:

> IMHO, whether a varibale is used or not has got to be one of the least
> important things of all (in no small part because it's easily
> discernable from nearby code).

I couldn't disagree more.

If you're binding a name to a value that will never be used, you're
doing me (the reader of the code) a great favour if you indicate
clearly and concisely that this value is not intended to be referenced
anywhere else. Saving time for the reader is a very important job of
the writer of code.

> Having said that, if you do think it's most important to document
> whether something is used, I would suggest not using "_" (because
> it's conflicts with gettext conventions) or "dummy" (because it's
> misleading) for it.

Agreed.

Note, too, that the ideal answer to this is "don't bind names at all
to values that will never be used". It's only because the specifics of
Python's 'for' statement require us to do this that we are discussing
the ramifications of what to do when what Python requires of us is
actually unnecessary for our purposes.

--
\ "Friendship is born at that moment when one person says to |
`\ another, 'What! You too? I thought I was the only one!'" -- |
_o__) C.S. Lewis |
Ben Finney

Carl Banks

unread,
May 12, 2008, 7:10:51 PM5/12/08
to
On May 12, 7:03 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:

> Carl Banks <pavlovevide...@gmail.com> writes:
> > IMHO, whether a varibale is used or not has got to be one of the least
> > important things of all (in no small part because it's easily
> > discernable from nearby code).
>
> I couldn't disagree more.
>
> If you're binding a name to a value that will never be used, you're
> doing me (the reader of the code) a great favour if you indicate
> clearly and concisely that this value is not intended to be referenced
> anywhere else. Saving time for the reader is a very important job of
> the writer of code.

I don't think knowing in advance whether a variable is going to be
used or not benefits readability.


Carl Banks

Terry Reedy

unread,
May 12, 2008, 7:21:41 PM5/12/08
to pytho...@python.org

"Ben Finney" <bignose+h...@benfinney.id.au> wrote in message
news:877ie06...@benfinney.id.au...

| So, when not using the values that come from the controlling iterator,
| it's good to make that explicit. If Python supported it, we might
| prefer to use no name at all for something that isn't used, but the
| 'for' syntax doesn't allow that.

But I presume it could if [target 'in'] were optional.

for range(n): <stuff to do n times>

It is possible this has been proposed and rejected,
but I have no specific memory.

tjr

Dave Parker

unread,
May 12, 2008, 8:07:30 PM5/12/08
to
On May 10, 8:19 pm, John Salerno <johnj...@NOSPAMgmail.com> wrote:
> It seems somewhat
> artificial to use the for loop to do something a certain number of
> times, like above.

I agree; it's a common flaw with lots of languages, not just Python.

I'd be inclined to use something like:

FOR 8 TIMES DO <statement>.

or:

REPEAT <statement> FOR 8 TIMES.

as a compromise between readability and machine-parsability.

If anyone has other suggestions, please post them here and I'll
implement one of them next weekend in Flaming Thunder.

George Sakkis

unread,
May 12, 2008, 9:52:49 PM5/12/08
to
On May 12, 7:03 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:

> Carl Banks <pavlovevide...@gmail.com> writes:
> > IMHO, whether a varibale is used or not has got to be one of the least
> > important things of all (in no small part because it's easily
> > discernable from nearby code).
>
> I couldn't disagree more.
>
> If you're binding a name to a value that will never be used, you're
> doing me (the reader of the code) a great favour if you indicate
> clearly and concisely that this value is not intended to be referenced
> anywhere else. Saving time for the reader is a very important job of
> the writer of code.

If you push this logic too far, you should del every name immediately
after the last statement it is used in the scope. I would generally
find less readable some code spread with del every few lines, micro-
managing the effective scope of each name. YMMV.

George

John Salerno

unread,
May 13, 2008, 12:01:59 AM5/13/08
to
Ben Finney wrote:

> I think that the idiom
>
> for unused in xrange(10):
> # do stuff with no reference to 'unused'
>
> is quite common. Is that what you're asking about?

Yes. I was more or less asking about the specific situation of using a
for loop to do something X number of times, but I think the more
generalized problem that everyone is talking about -- using a counter
variable that is never referenced in the loop -- probably puts the point
I was trying to make in a better light.

The reason I even brought this up is because I remember someone saying a
while back (probably here on the newsgroup) that the true use of a for
loop was to iterate through a sequence (for the purpose of using that
sequence), not to do something X number of times. Once they made this
comment, I suddenly saw the for loop in a new (and I believe purer)
light. That was the first time I realized what it was really meant
to do.

Using something like:

for unused in xrange(10):
# do stuff 10 times

suddenly seemed to me like a hackish way to replace

for (int i=0; i<10; i++) {
// do stuff 10 times;
}

Not that I think the above code (C#) looks all that elegant either. But
in C# there is a distinction between the above, and this:

foreach (int i in sequence)
// do something;

which is more closely related to the Python for loop.

Now, you could easily make the argument that the Python for loop is a
much simpler tool to accomplish *both* of the above, and I suppose that
makes sense. Seems a little silly to have two separate for loops to do
these things. I just wasn't sure if the "counter" version of the Python
for loop was considered slightly unpythonic.

Terry Reedy

unread,
May 13, 2008, 3:11:30 AM5/13/08
to pytho...@python.org

"John Salerno" <john...@NOSPAMgmail.com> wrote in message
news:482912b7$0$11641$607e...@cv.net...

| The reason I even brought this up is because I remember someone saying a
| while back (probably here on the newsgroup) that the true use of a for
| loop was to iterate through a sequence (for the purpose of using that
| sequence), not to do something X number of times.

I believe the specific context was to counteract some people's tendency to
write
for i in range(len(seq)): do stuff with seq[i]
when they would better (more Pythonically) write
for item in seq: do stuff with item
or even
for i,item in enumerate(seq): do stuff with i and item.

One subtle but real advantage is that the latter two forms work with
iterables that do not have a known-ahead length or which even continue
indefinitely.

| Once they made this
| comment, I suddenly saw the for loop in a new (and I believe purer)
| light. That was the first time I realized what it was really meant
| to do.

That is an important insight. But to me it does not negate the "do
something n times" usage when there is no iterable other than range to
iterate. Do note that range has *not* been removed from 3.0 and that its
main intended usage is for looping.

| Now, you could easily make the argument that the Python for loop is a
| much simpler tool to accomplish *both* of the above, and I suppose that
| makes sense.

Yes. Python leans toward minimalism. Proposals for various
special-purpose loopin constructs have been rejected. For-loops cover most
looping needs; while-loops cover everything else.

Terry Jan Reedy

Marc 'BlackJack' Rintsch

unread,
May 13, 2008, 3:27:55 AM5/13/08
to
On Mon, 12 May 2008 11:23:07 -0700, Carl Banks wrote:

> On May 12, 3:42 am, Ben Finney <bignose+hates-s...@benfinney.id.au>
> wrote:
>> Because of the precedent of those names, choosing one of those names
>> doesn't make it clear to the reader that the value is never used;
>
>
> Why is it even necessary to document this? This is the thing that
> baffles me the most about this thread.

I do it (with a "special" name) because static source checkers issue a
warning for unused variables.

Ciao,
Marc 'BlackJack' Rintsch

Dave Parker

unread,
May 13, 2008, 9:14:34 AM5/13/08
to
> REXX's loop construct subsumes all the common uses... And worse, it
> appears that a repetition and a condition can be part of the single
> statement.

Thank you for pointing out the REXX examples. I am a Kedit user, but
had forgotten about the REXX do-loops. I'll keep them in mind when I
add an easy way to "do this n times" to Flaming Thunder this weekend.

On May 11, 8:53 pm, Dennis Lee Bieber <wlfr...@ix.netcom.com> wrote:
> On Mon, 12 May 2008 00:43:08 GMT, Jonathsn Cronin <j...@theworld.com>
> declaimed the following in comp.lang.python:
>
> > I agree in principle; the first is iteration and the second is repetition.
> > In Python, the common idiom for a fixed number of repetitions is iterating
> > over a number range.  This is true in most languages I am familiar with,
> > probably because fixed repetition, where you don't care about the "index"
> > value, is rarely used.
>
> > The only language I've used that does have fixed repetition is an (old)
> > dialect of lisp, and I'm not sure it even made it into Common Lisp.  
> > Smalltalk and Ruby do have fixed repetition.
>
>         REXX's loop construct subsumes all the common uses... And worse, it
> appears that a repetition and a condition can be part of the single
> statement.
>
> DO FOREVER
> ...
> END
>
> DO repeatcount
> ...
> END
>
> DO loopvar=first TO last BY step FOR reptcount
> ...
> END
>
> (where "TO last", "BY step", "FOR reptcount" are all optional clauses!)
>
> DO WHILE conditional
> ...
> END
>
> DO UNTIL conditional
> ...
> END
>
>         Mixing modes
>
> DO loopvar=first BY step UNTIL conditional
> ...
> END
>
> Hmmm, looks like it's been extended for container objects (those that
> support MAKEARRAY):
>
> DO item OVER container
> ...
> END
> --
>         Wulfraed        Dennis Lee Bieber               KD6MOG
>         wlfr...@ix.netcom.com              wulfr...@bestiaria.com
>                 HTTP://wlfraed.home.netcom.com/
>         (Bestiaria Support Staff:               web-a...@bestiaria.com)
>                 HTTP://www.bestiaria.com/

Larry Bates

unread,
May 13, 2008, 9:25:40 AM5/13/08
to
John Salerno wrote:
> I know it's popular and very handy, but I'm curious if there are purists
> out there who think that using something like:
>
> for x in range(10):
> #do something 10 times
>
> is unPythonic. The reason I ask is because the structure of the for loop
> seems to be for iterating through a sequence. It seems somewhat

> artificial to use the for loop to do something a certain number of
> times, like above.
>
> Anyone out there refuse to use it this way, or is it just impossible to
> avoid?

I use it quite often, especially if I want to implement a fixed number of
retries on a communications channel.

-Larry

Lie

unread,
May 13, 2008, 10:20:14 AM5/13/08
to

What was unPythonic, I think, as most people would agree, is to use
for like this:

--
for i in xrange(len(lst)):
pass
--

In VB, my language before Python, I've never used For Each even for a
sequence (Array, in VB), it seems too messy back then. Now, with
Python that only allowed a foreach statement, I realized that I never
really needed a for i in range(10) at all. Most of the time the places
where I need to do that is where the code is just a test code that
loops a certain number of times (with randomized input data), almost
never (probably never) met that in a real program code. And even in
some of those cases, the variables are usually used too (as a test
argument to the function being tested) or for logging purpose.

On May 13, 8:25 pm, Larry Bates <larry.ba...@websafe.com`> wrote:
(snip)


> I use it quite often, especially if I want to implement a fixed number of
> retries on a communications channel.
>
> -Larry

That still have semantic meaning: 'tries'. If it was me, I'll go to
the trouble of giving names, since I would use it for logging or
informational purpose ('first try' 'second try' 'third try' 'no more
try').

I've never really met a real "do something n times" case, where the
variable doesn't hold any semantic meaning that I don't want to use
and is not a test case.

For me, a _ (or any other dummy variable[1]) is good enough and it's
easy to change if later I realized that I actually need to use the
variable. I agree though, that i, j, k for unused name is a bad choice
because single letter names is in common usage in mathematics.

[1] PEP 8 is useless if a certain code base has other agreed
convention, as long as the name used for a unused name in certain code
base is consistent (and probably documented), it never becomes a
problem.

Lie

unread,
May 13, 2008, 10:58:06 AM5/13/08
to

On my last message, I'm tempted not to say: "We need to have /dev/null
for Python" though I proved to fail.

John Nagle

unread,
May 13, 2008, 1:20:41 PM5/13/08
to
Matt Nordhoff wrote:
> John Salerno wrote:
>> I know it's popular and very handy, but I'm curious if there are purists
>> out there who think that using something like:
>>
>> for x in range(10):
>> #do something 10 times
>>
>> is unPythonic. The reason I ask is because the structure of the for loop
>> seems to be for iterating through a sequence. It seems somewhat
>> artificial to use the for loop to do something a certain number of
>> times, like above.
>>
>> Anyone out there refuse to use it this way, or is it just impossible to
>> avoid?
>
> Well, you should use "xrange(10)" instead of "range(10)".

CPython really is naive. That sort of thing should be a
compile-time optimization.

John Nagle

Ben Finney

unread,
May 13, 2008, 7:34:31 PM5/13/08
to
John Nagle <na...@animats.com> writes:

> Matt Nordhoff wrote:
> > Well, you should use "xrange(10)" instead of "range(10)".
>
> CPython really is naive. That sort of thing should be a
> compile-time optimization.

Or even a case of the 'xrange' behaviour making 'range' obsolete.

Which, as I pointed out earlier in the thread, it is in Python 3.0.

--
\ "Yesterday I parked my car in a tow-away zone. When I came back |
`\ the entire area was missing." -- Steven Wright |
_o__) |
Ben Finney

Marc 'BlackJack' Rintsch

unread,
May 14, 2008, 2:37:55 AM5/14/08
to
On Tue, 13 May 2008 10:20:41 -0700, John Nagle wrote:

> Matt Nordhoff wrote:
>
>> Well, you should use "xrange(10)" instead of "range(10)".
>
> CPython really is naive. That sort of thing should be a
> compile-time optimization.

It's not naive, it can't know at compile time what object is bound to the
name `xrange` at runtime.

Ciao,
Marc 'BlackJack' Rintsch

cokof...@gmail.com

unread,
May 14, 2008, 3:24:39 AM5/14/08
to

I think he meant you should just use xrange over range at all times.

Graham Breed

unread,
May 17, 2008, 1:04:44 AM5/17/08
to
George Sakkis wrote:

> If you push this logic too far, you should del every name immediately
> after the last statement it is used in the scope. I would generally
> find less readable some code spread with del every few lines, micro-
> managing the effective scope of each name. YMMV.

Yes, but ... how about

for i in range(10):
del i
do stuff

?

It makes it clear you aren't using the index and ensures you
get a run-time error if you clobbered an existing variable.


Graham

Dave Parker

unread,
May 19, 2008, 10:51:41 PM5/19/08
to
Your point about for-loops was applicable not only to Python, but to
many other programming languages. So in response, I've added two new
for-loop variations to Flaming Thunder.

The two new variations are for-forever-do and for-expression-times-do.
For-forever allows you to explicitly create infinite loops, and for-
expression-times allows you to do something a specific number of times
without having to declare a looping variable if you don't need one.
Examples:

Write "Fa". For 8 times do write "-la".

For forever do
(
Write "Do you know the definition of insanity? ".
Read response.
).

On May 10, 8:19 pm, John Salerno <johnj...@NOSPAMgmail.com> wrote:
> I know it's popular and very handy, but I'm curious if there are purists
> out there who think that using something like:
>
> for x in range(10):
>     #do something 10 times
>

> isunPythonic. The reason I ask is because the structure of the for loop

0 new messages