Using reverse iteration to clean up a list

T

tkpmep

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[0]:
L[i-1][2] += L[2]
del L

Is there a simpler way to do this using the new reverse iteration
facility in Python 2.4?

Thomas Philips
 
P

Paul Rubin

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()
 
J

John Machin

Paul said:
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?
 
L

Luis M. Gonzalez

Well, I'm not sure if this is what you want, but you could use a
dictionary:
if d.has_key(i):
d += e
else:
d = e

 
M

Michael Hoffman

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.
 
T

tkpmep

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
 
M

Michael Hoffman

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top