[Tutor] Traversing lists or getting the element you want.

Dave Angel davea at davea.name
Mon Feb 3 01:22:45 CET 2014


 Kipton Moravec <kip at kdream.com> Wrote in message:
> I am new to Python, and I do not know how to traverse lists like I
> traverse arrays in C. This is my first program other than "Hello World".
> I have a Raspberry Pi and they say Python is the language of choice for
> that little machine. So I am going to try to learn it.
> 
> 
> I have data in the form of x, y pairs where y = f(x) and is non linear.
> It comes from a .csv file.
> 

Sounds to me that you've just got a y list; your x list has the
 implicit assumption of being range (165,660)

> In this case x is an integer from 165 to 660 so I have 495 data sets. 
> 
> I need to find the optimal locations of three values of x to piecewise
> linear estimate the function. 
> 

You're making the unspoken assumption that each line starts and
 ends exactly on a data point.  That won't give you the minimum
 error in general,  but perhaps it is an extra oddball restriction
 in the assignment. 


> 
> So I need to find i, j, k so 165 < i < j < k < 660 and the 4 line
> segments [(165, f(165)), (i, f(i))], [(i, f(i)), (j, f(j))], [(j, f(j),
> (k, f(k))], [(k, f(k)), (660, f(660))].
> 
> 
> The value I need to minimize is the square of the difference between the
> line estimate and the real value at each of the 495 points. 

No it appears to be the sum of the squares. 

> 
> 
> I can do this in C. To keep it simple to understand I will assume the
> arrays x[] and y[] and minsum, mini, minj, and mink are global.
> 

That may seem to simplify the c but it's not pythonic.  If a
 function calculates 4 values, it should return 4 values, 
 presumably as a tuple.

> 
> I have not tested this but this is what I came up with in C. Assuming
> x[] and y[] are already filled with the right values.
> 
> 
> int x[495];
> double y[495];
> max_elements = 495;
> double minsum;
> int mini, minj, mink
> 
> 
> void minimize(int max_elements)
> 
> {
>     minsum = 9999999999999.0; // big big number
> 
>     for (i=2; i<max_elements-6;i++)
>         for (j=i+2; j< max_elements -4; j++)
>              for (k=j+2; k< max_elements-2;k++)
>              {
>                 sum = error(0,i);
>                 sum += error(i,j);
>                 sum += error(j,k);
>                 sum += error(k,495)
> 
>                 if (sum < minsum) 
>                 {
>                     minsum = sum;
>                     mini = i;
>                     minj = j;
>                     mink = k;
>                 } 
>              }
> }
> 
> 
> double error(int istart, int iend)
> {
> 
> // linear interpolation I can optimize but left 
> // it not optimized for clarity of the function
> 
>     int m;
> 
>     double lin_estimate;
> 
>     double errorsq;
> 
>     errorsq = 0;
> 
>     for (m=istart; m<iend; m++)
>     {
>         lin_estimate = y[istart] + ((y[iend] – y[istart]) * 
>                        ((x[m] – x[istart]) / (x[iend] – x[istart])));
> 
>         errorsq += (lin_estimate – y[m]) * (lin_estimate – y[m]);
>     } 
> 
>     return (errorsq);
> 
> }
> 
> 
> 
> At the end the three values I want are mini, minj, mink;
> or x[mini], x[minj], x[mink]
> 
> 
> So how do I do this (or approach this) in Python?
> 
> 
 for (i=2; i<max_elements-6;i++)

could transliterate to 

      for i in range ( 2, max_elements-6):


although usually you're better off looping directly on the list
 involved. 

Study what each loop does --

for  a, b in zip (x, y):

for index, value in enumerate (y):


By the way, I think the x list starting value cancels out, and you
 might be able to ignore it except at the very end when you add it
 to mini,  minj,  and mink. 



-- 
DaveA



More information about the Tutor mailing list