transforming list

George Sakkis george.sakkis at gmail.com
Wed Oct 24 07:34:42 CEST 2007


On Oct 23, 10:46 pm, james_027 <cai.hai... at gmail.com> wrote:
> hi,
>
> i have a list from a resultset like this
> 1,"Chicago Bulls",,,""
> 2,"Cleveland Caveliers",,,""
> 4,"Detroit Pistons",1,"23686386.35"
> 4,"Detroit Pistons",2,"21773898.07"
> 4,"Detroit Pistons",3,"12815215.57"
> 4,"Detroit Pistons",4,"48522347.76"
> 4,"Detroit Pistons",5,"28128425.99"
> 4,"Detroit Pistons",6,"15681603.08"
> 4,"Detroit Pistons",8,"12627725.03"
> 4,"Detroit Pistons",9,"11417.00"
> 4,"Detroit Pistons",10,"945689.22"
> 4,"Detroit Pistons",11,"818246.57"
> 4,"Detroit Pistons",12,"1154292.77"
> 5,"Phoenix Suns",1,"23211445.97"
> 5,"Phoenix Suns",3,"11268469.53"
> 5,"Phoenix Suns",4,"49913569.61"
> 5,"Phoenix Suns",5,"26035236.09"
> 5,"Phoenix Suns",7,"113953310.50"
> 5,"Phoenix Suns",8,"17091769.84"
> 5,"Phoenix Suns",10,"818569.99"
> 5,"Phoenix Suns",11,"824602.19"
> 5,"Phoenix Suns",12,"1142018.11"
>
> and I wish to transform it into something like this
>
> 1, "Chicago Bulls", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> 2, "Cleveland Caveliers", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> 4, "Detroit Pistons", 23686386.35, 21773898.07, 12815215.57,
> 48522347.76, 28128425.99, 15681603.08, 0, 12627725.03, 11417.00,
> 945689.22, 818246.57, 1154292.77
> 5, "Phoenix Suns", 23211445.97, 0, 11268469.53, 499113569.61,
> 26035236.09, 0, 113953310.50, 17091769.84, 0, 818569.99, 824602.19,
> 1142018.11
>
> currently my solution is something like this the rows is the original
> list which is list of list ... the report is a list of list with the
> new arrangement that I want.
>
>         report = []
>         report_item = None
>         temp_c_id = 0
>         for row in rows:
>             if not row[0] == temp_c_id:
>                 temp_c_id = row[0]
>                 if report_item: report.append(report_item)
>                 report_item = [row[0], row[1], 0, 0, 0, 0, 0, 0, 0, 0,
> 0, 0, 0, 0]
>             if row[2]:
>                 report_item[row[2]+1] = row[3]

This doesn't print the last row (5, "Phoenix Suns", ...); you need one
more append outside the loop (if report_item:
report.append(report_item)).

> I feel this solution is not that good, can I make this more pythonic?!

Sure; get familiar with a swiss-knife module, itertools, and in
particular for this task, groupby:


from operator import itemgetter
from itertools import groupby, chain

def group_roster(rows, num_stats=12):
    # group the rows by their first two elements
    # Caveat: the rows should already be sorted by
    # the same key
    for key,group in groupby(rows, itemgetter(0,1)):
        stats = [0.0] * num_stats
        for row in group:
            if row[2]: stats[int(row[2])-1] = float(row[3])
        yield list(chain(key,stats))

if __name__ == '__main__':
    import csv
    for row in group_roster(csv.reader(open('roster.txt'))):
        print row


HTH,
George




More information about the Python-list mailing list