By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,818 Members | 1,282 Online
Bytes IT Community
+ Ask a Question
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
Share this Question
Share on Google+
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.