443,818 Members | 1,282 Online
Need help? Post your question and get tips & solutions from a community of 443,818 IT Pros & Developers. It's quick & easy.

# Using reverse iteration to clean up a list

 P: n/a I have list of lists of the following form L=[['A', 100], ['B', 300], ['A', 400], ['B', -100]] I want to aggregate these lists, i.e. to reduce L to L=[['A', 500], ['B', 200]] #500 = 100+400, 200=300-100 Here's how I have done it: L.sort() for i in range(len(L),0,-1): if L[i-1][0]=L[i][0]: L[i-1][2] += L[i][2] del L[i] Is there a simpler way to do this using the new reverse iteration facility in Python 2.4? Thomas Philips Jul 18 '05 #1
6 Replies

 P: n/a tk****@hotmail.com writes: I have list of lists of the following form L=[['A', 100], ['B', 300], ['A', 400], ['B', -100]] I want to aggregate these lists, i.e. to reduce L to L=[['A', 500], ['B', 200]] #500 = 100+400, 200=300-100 How about: v = {} for name,val in L: v[name] = v.get(name, 0) + val L = v.items() Jul 18 '05 #2

 P: n/a Paul Rubin wrote: tk****@hotmail.com writes: I have list of lists of the following form L=[['A', 100], ['B', 300], ['A', 400], ['B', -100]] I want to aggregate these lists, i.e. to reduce L to L=[['A', 500], ['B', 200]] #500 = 100+400, 200=300-100 How about: v = {} for name,val in L: v[name] = v.get(name, 0) + val L = v.items() Followed by L.sort() if the OP really needs his list sorted. Alternatively, he may prefer to leave it in a dict; in fact, if he had been using a dict all along and maintaining it on the fly by "v[name] = v.get(name, 0) + val", he wouldn't need to batch-fix his data structure now. tkpmep, how did you get this list of lists with duplicate keys and additive values? What do you want to do with it next? Jul 18 '05 #3

 P: n/a Well, I'm not sure if this is what you want, but you could use a dictionary: d={} for i,e in L: if d.has_key(i): d[i] += e else: d[i] = e d {'A': 500, 'B': 200} Jul 18 '05 #4

 P: n/a tk****@hotmail.com wrote: L=[['A', 100], ['B', 300], ['A', 400], ['B', -100]] I want to aggregate these lists, i.e. to reduce L to L=[['A', 500], ['B', 200]] #500 = 100+400, 200=300-100 """ from itertools import groupby from operator import itemgetter [(key, sum(item[1] for item in sublist)) for key, sublist in groupby(sorted(L, key=itemgetter(0)), itemgetter(0))] """ OK, strictly speaking that will get you a list of tuples instead of a list of lists, but that's easy enough to fix if you insist on a list of lists. Tuples are generally used for heterogeneous fixed-length sequences. -- Michael Hoffman Jul 18 '05 #5

 P: n/a Thank you all so much for the generous dollop of help: the dictionary suggestion is particularly helpful. The problem arises as follows: A software application stores the securities held in a portfolio in a ..csv file, one row per security, with three colulmns. The first has a security identifier or descriptor (such as a ticker) the second has a single letter that identifies the type of the identifier (T for ticker, C for cusip etc.) and the third has the number of shares. A typical line looks like this: IBM, T, 500 I need to read in one or more portfolios and aggregate their holdings. To do so, I read in the portfolios using the csv package, convert each line to a list and then append it to a list of lists. Eventually the list of lists contains all the securities, and can then be sorted and aggregated. I suppose I could convert it instead to a dictionary, and the most natural key would be the first two items, i.e. a portfolio containing just 500 shares of IBM ought to be represented as {("IBM", "T") : 500 } How can I translate the data I read in using csv.reader into a dictionary? Thomas Philips Jul 18 '05 #6

 P: n/a tk****@hotmail.com wrote: Thank you all so much for the generous dollop of help: the dictionary suggestion is particularly helpful. The problem arises as follows: A software application stores the securities held in a portfolio in a .csv file, one row per security, with three colulmns. The first has a security identifier or descriptor (such as a ticker) the second has a single letter that identifies the type of the identifier (T for ticker, C for cusip etc.) and the third has the number of shares. A typical line looks like this: IBM, T, 500 I need to read in one or more portfolios and aggregate their holdings. To do so, I read in the portfolios using the csv package, convert each line to a list and then append it to a list of lists. Eventually the list of lists contains all the securities, and can then be sorted and aggregated. I suppose I could convert it instead to a dictionary, and the most natural key would be the first two items, i.e. a portfolio containing just 500 shares of IBM ought to be represented as {("IBM", "T") : 500 } How can I translate the data I read in using csv.reader into a dictionary? portfolio = {} for row in csv.reader(infile): key = tuple(row[:2]) portfolio[key] = portfolio.get(key, 0) + int(row[2]) You could also do a groupby solution with itemgetter(slice(0, 2))--thanks to Steven Bethard for recently pointing out the possibility here of doing that. I'd go with the dict for this application though. -- Michael Hoffman Jul 18 '05 #7

### This discussion thread is closed

Replies have been disabled for this discussion.