Bob Unger
Bob Unger

Reputation: 341

How do I generate a table from a list

I have a list that contains sublists with 3 values and I need to print out a list that looks like:

list picture

I also need to compare the third column values with eachother to tell if they are increasing or decreasing as you go down.

bb = 3.9
lowest = 0.4
#appending all the information to a list
allinfo= []
while bb>=lowest:
    everything = angleWithPost(bb,cc,dd,ee)
    allinfo.append(everything)
    bb-=0.1

I think the general idea for finding out whether or not the third column values are increasing or decreasing is:

#Checking whether or not Fnet are increasing or decreasing
ii=0
while ii<=(10*(bb-lowest)):
    if allinfo[ii][2]>allinfo[ii+1][2]:
        abc = "decreasing"
    elif allinfo[ii][2]<allinfo[ii+1][2]:
        abc = "increasing"
    ii+=1

Then when i want to print out my table similar to the one above.

jj=0
while jj<=(10*(bb-lowest))
    print "%8.2f %12.2f %12.2f %s" %(allinfo[jj][0], allinfo[jj][1], allinfo[jj][2], abc)
    jj+=1

here is the angle with part

def chainPoints(aa,DIS,SEG,H):
    #xtuple x chain points
    n=0
    xterms = []
    xterm = -DIS
    while n<=SEG:
        xterms.append(xterm)
        n+=1
        xterm = -DIS + n*2*DIS/(SEG)
#
    #ytuple y chain points
    k=0
    yterms = []
    while k<=SEG:
        yterm = H + aa*m.cosh(xterms[k]/aa) - aa*m.cosh(DIS/aa)
        yterms.append(yterm)
        k+=1
    return(xterms,yterms)
#
#
def chainLength(aa,DIS,SEG,H):
    xterms, yterms = chainPoints(aa,DIS,SEG,H)# using x points and y points from the chainpoints function
    #length of chain
    ff=1
    Lterm=0.
    totallength=0.
    while ff<=SEG:
        Lterm = m.sqrt((xterms[ff]-xterms[ff-1])**2 + (yterms[ff]-yterms[ff-1])**2)
        totallength += Lterm
        ff+=1
    return(totallength)
#

def angleWithPost(aa,DIS,SEG,H):
    xterms, yterms = chainPoints(aa,DIS,SEG,H)
    totallength = chainLength(aa,DIS,SEG,H)
    #Find the angle
    thetaradians = (m.pi)/2. + m.atan(((yterms[1]-yterms[0])/(xterms[1]-xterms[0])))
    #Need to print out the degrees
    thetadegrees = (180/m.pi)*thetaradians
    #finding the net force
    Fnet = abs((rho*grav*totallength))/(2.*m.cos(thetaradians))
    return(totallength, thetadegrees, Fnet)

Upvotes: 0

Views: 181

Answers (2)

Justin Poehnelt
Justin Poehnelt

Reputation: 3454

Basically you want to add a 4th column to the inner list and print the results?

#print headers of table here, use .format for consistent padding

previous = 0 
for l in outer_list:
    if l[2] > previous:
        l.append('increasing')
    elif l[2] < previous:
        l.append('decreasing')
    previous = l[2]

    #print row here use .format for consistent padding

Update for list of tuples, add value to tuple:

import random
outer_list = [ (i, i, random.randint(0,10),)for i in range(0,10)]

previous = 0
allinfo = []
for l in outer_list:
    if l[2] > previous:
        allinfo.append(l +('increasing',))
    elif l[2] < previous:
        allinfo.append(l +('decreasing',))
    previous = l[2]

   #print row here use .format for consistent padding

print(allinfo)

This most definitely can be optimized and you could reduce the number of times you are iterating over the data.

Upvotes: 1

Javier
Javier

Reputation: 2776

Review this Python2 implementation which uses map and an iterator trick.

from itertools import izip_longest, islice
from pprint import pprint


data = [
    [1, 2, 3],
    [1, 2, 4],
    [1, 2, 3],
    [1, 2, 5],
]


class AddDirection(object):
    def __init__(self):
        # This default is used if the series begins with equal values or has a
        # single element.
        self.increasing = True

    def __call__(self, pair):
        crow, nrow = pair
        if nrow is None or crow[-1] == nrow[-1]:
            # This is the last row or the direction didn't change. Just return
            # the direction we previouly had.
            inc = self.increasing
        elif crow[-1] > nrow[-1]:
            inc = False
        else:
            # Here crow[-1] < nrow[-1].
            inc = True
        self.increasing = inc

        return crow + ["Increasing" if inc else "Decreasing"]

result = map(AddDirection(), izip_longest(data, islice(data, 1, None)))

pprint(result)

The output:

pts/1$ python2 a.py 
[[1, 2, 3, 'Increasing'],
 [1, 2, 4, 'Decreasing'],
 [1, 2, 3, 'Increasing'],
 [1, 2, 5, 'Increasing']]

Whenever you want to transform the contents of a list (in this case the list of rows), map is a good place where to begin thinking.

When the algorithm requires data from several places of a list, offsetting the list and zipping the needed values is also a powerful technique. Using generators so that the list doesn't have to be copied, makes this viable in real code.

Finally, when you need to keep state between calls (in this case the direction), using an object is the best choice.

Sorry if the code is too terse!

Upvotes: 1

Related Questions