Re: Using reverse iteration to clean up a list
[EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Using reverse iteration to clean up a list
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Using reverse iteration to clean up a list
[EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Using reverse iteration to clean up a list
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} >>> -- http://mail.python.org/mailman/listinfo/python-list
Re: Using reverse iteration to clean up a list
Paul Rubin wrote: > [EMAIL PROTECTED] 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? -- http://mail.python.org/mailman/listinfo/python-list
Re: Using reverse iteration to clean up a list
[EMAIL PROTECTED] 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() -- http://mail.python.org/mailman/listinfo/python-list
Using reverse iteration to clean up a list
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 -- http://mail.python.org/mailman/listinfo/python-list