can't assign value to array element

Carl Banks imbosol at vt.edu
Sun Nov 3 23:50:06 EST 2002


Joe Heafner wrote:
> Hi.
> In my attempt to seriously learn Python (2.2.1 running on Mac OS X), I've 
> been trying to code some simple numerical algorithms. Here is my code for 
> one routine:
> 
> a=0.
> b=1.4
> y0=0.
> m=10
> 
> h = (b-a)/m
> t = zeros(m, Float)
> t[0] = a
> y = zeros(m, Float)
> y[0] = b
> 
> for j in range(0,m,1):
>    print j # for debugging purposes
>    t = t[j]
>    y = y[j]
>    k1 = h*fprimexy(t,y)
>    k2 = h*fprimexy(t+h/2., y+0.5*k1)
>    k3 = h*fprimexy(t+h/2., y+0.5*k2)
>    k4 = h*fprimexy(t+h, y+k3)
>    y[j+1] = y+(k1+2.*k2+2.k3+k4)/6.
>    t[j+1] = a+h*(j+1)
> 
> When run, this code give the error "TypeError: object does not support 
> item assignment" for hte next to last line. I presume the last line would 
> give the same error. I'm very new to Python and haven't been able to find 
> documentation about htis specific problem, and I've been working 
> (literally) all day on this. What am I doint wrong? I'd appreciate any 
> help.


A variable name can't be used as both an array and a scalar (i.e. this
isn't Perl).  The line

    y = y[i]

rebinds y to the value of the scalar y[i], and so y is no longer an
array.  When you try to index it later, Python complains because it
now considers y a scalar.

The solution is to rename the scalar y, maybe to yi or something.
Same thing with t.

I have couple other minor suggestions:

1. Since you're interested in numerical methods, you're probably
   interested in speed.  You should put the code inside a function,
   like this:

   def main():
       <your code here>
   main()

   This is the single easiest thing you can do to speed up code.
   Variables defined inside a function are faster than those defined
   at top level.  (Although for some numerical applications, the
   numerical time dominates and it won't make too much of a
   difference.)

2. If you intend to do long simulations (more than a few thousand time
   steps), you might want to use xrange(0,m,1) instead of
   range(0,m,1).  The reason is that range allocates a large block of
   memory (probably about m*4 bytes) and fills it with sequential
   integers (which might involve more allocation), all before the
   first iteration.  xrange returns integers on-the-fly each
   iteration.


-- 
CARL BANKS



More information about the Python-list mailing list