l = range(int(1E9))

Terry Reedy tjreedy at udel.edu
Sat May 2 18:41:46 EDT 2015


On 5/2/2015 11:26 AM, BartC wrote:

> When I first looked at Python 20 or so years ago this seemed to be the
> standard way of writing a for-loop:
>
> for i in range(N):
>     ....

As Mark said, the actual syntax was originally

for item in sequence: ...

where sequence technically meant an object with a .__getitem__(x) method 
that either returned an item or raised IndexError.  In 2.2, 'sequence' 
was replaced by the more general concept 'iterable'.

In python, 'for' is and has always been an abbreviation of 'for each' or 
'foreach', as used in other languages. C for loops are not 'for each' 
loops but are initialized while loops, and are so explained in K&R's 
book, page 56.

'''
for (initializer; condition; update;) body

is equivalent to

initializer
while (condition) {
     body
     update;
}
...
Whether to use while or for is largely a matter of taste.
'''

(I substituted 'initializer', 'condition', 'update' for 'expr1', 
'expr2', and 'expr3' as more meaningful.)  The proper translation of a C 
for loop to Python is the translation of the equivalent C while loop. 
Translating to a Python 'for range' loop is a bit of a mis-translation. 
  One should not be surprised if non-equivalent code behaves differently.

> I remember being completely astonished at the time that 'range' actually
> created a list of values from 0 to N-1.

The purpose and *documented* behavior of range was to produce an 
arithmetic sequence.  Map, filter, dict.keys, dict.values, dict.items, 
many others functions also returned lists.  In Python3, the ones I named 
above and some others now return 'less spacious' iterables.

> Python was already known to be slow yet it deliberately crippled itself
> by using just about the slowest method imaginable of executing a simple
> iterative loop? By first creating a list of a million objects!

No, you were also free to do the sensible thing when you did not need a 
concrete arithmetic sequence (list).

n = 0
while n < 1000000:
     pass
     n = n+1

> And sometimes you weren't even interested in the values but just wanted
> to execute something N times so it was a wasted effort.

# even simpler
n = 1000000
while n:
     pass
     n -= 1

Using for ... range() is a convenient abbreviation of either pattern. 
It works for small values of n, it did not work for large values.  When 
Python 1.0 was released in Feb 1992, memory for many system was limited 
to a megabyte or less. At that time, range(1000000) was an impossible 
object, so no one aware of memory constraints would try to create it.

-- 
Terry Jan Reedy




More information about the Python-list mailing list