Dumb python questions

Paul Rubin phr-n2001 at nightsong.com
Wed Aug 15 22:36:45 EDT 2001


quinn at hork.ugcs.caltech.edu (Quinn Dunkan) writes:
> >What's wanted is something equivalent to
> >
> >   sum = 0
> >   i = 1
> >   while i <= 100 :
> >      sum = sum + i
> >      i = i + 1
> 
> In python, as in most languages (especially most functional languages),
> space and time efficiency is not the goal.  It's possibly a goal, but not
> *the* goal.  Programmer efficiency is the goal.

Well, I'd like to think getting practical, runnable programs is also
a goal, and modularity is a goal, e.g. rather than a fixed limit of 100
you're much more likely to code something like

   def sum(n): 
     s=0
     for i in range(n+1):
        s = s + i
     return s

> I have a feeling that you're not really running out of memory because of your
> 100 element lists.  Instead, I think some assembly-loving part of you,
> fiercely devoted to that tin god eifficiency, is exclaiming "but it's not as
> efficient as it could be!  forget the big picture, optimization is the key!".

No not for 100 element lists.  But if you want to compute sum(100)
today, you may want sum(1000000000) tomorrow.  But the natural and
obvious way to write the code then crashes from running out of memory.

> Ignore that annoying little voice.  Wait until you actually have a problem, in
> memory or speed.  Then find out which part of your program has the problem.
> Then use a less naive algorithm:
> 
> def sum(low, high):
>     p = high - low + 1
>     if p % 2:
>         return (low + high) * (p // 2) + (low + high)//2
>     else:
>         return (low + high) * (p // 2)

Well, you could actually just say

  def sum(low,high): 
     return (high+low)*(high-low+1)/2

(think about it).  However, that's entirely beside the point, which is
the most natural idiom for doing something n times, the equivalent of
"do i=1,n" in Fortran or "for i=1 to n" in Basic, goes and allocates
a potentially enormous amount of memory completely unnecessarily.
The summation example was just an illustration, not a computation
that anyone would actually want to do that way.

If it makes you feel better about algorithms, suppose instead you're
adding up just the primes instead of all the numbers:

  def sum_primes(n):  # sum of all primes < n
    s=0   
    for i in range(n):
      if is_prime (i): s=s+i
    return s

Now you run sum_primes(100) and it works fine, so you run
sum_primes(100000000) expecting it to take a few hours.  Instead it
fills several gigabytes of virtual memory and thrashes its brains out.
I don't see any obvious simple algorithmic improvements but it would
sure be nice if there was a looping construct that did the obvious
thing and simply counted through the range instead of allocating a
sequence.

> >Here's another one: the print statement puts a gratuituous space after
> >each thing you print.  So
> >
> >   for i in ['a','b','c']:
> >     print i,
> >
> >prints "a b c " instead of "abc".
> 
> The spaces are as gratuitous as all the spaces you put in between your words.

The spaces that I put between my words are put there by me, not by Emacs.
If I want to leave out the spaces, Emacsdoesn'tstopme. 

> It has a lot of common sense: spaces seperate things nicely.  'print' is
> supposed to be quick and easy to use for printing out short messages.  That's
> why it's a statement (no parens), automatically converts its arguments to
> strings, puts spaces in between its elements, and puts a newline on the end (I
> personally wouldn't mind if we dropped the "print foo," syntax, which is
> irregular and tends to lead to confusing extraneous softspace spaces).  If
> 'print' didn't put in all those gratuitous spaces and newlines, I'd wind up
> having to put them in by hand myself most of the time (as I do in some other
> languages).

The issue is that if you want them, it's easy to put them in, but if
you don't want them and the print statement puts them in anyway, it's
not so easy to get rid of them.  I think your objection to the extraneous
spaces from "print foo," is the exact same thing I'm objecting to, but
the solution is for the print statement to just print what you tell it,
without inserting extra spaces.

> If you want "low level" control over your IO, use the low level
> interface: sys.stdout.write.  'print' is optimized for casual use.
> You can also use the string formatting operator, %.

Yes, but if you have to resort to such tricks as sys.stdout.write, it
makes Python less pleasant to program in.  Is there a way to get rid
of the extra space with the string formatting operator?



More information about the Python-list mailing list