Re: Using reverse iteration to clean up a list

2005-03-13 Thread Michael Hoffman
[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

2005-03-13 Thread 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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Using reverse iteration to clean up a list

2005-03-13 Thread Michael Hoffman
[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

2005-03-12 Thread Luis M. Gonzalez
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

2005-03-12 Thread John Machin

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

2005-03-12 Thread Paul Rubin
[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

2005-03-12 Thread 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[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