Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Search for mapping solution (http://www.velocityreviews.com/forums/t319313-search-for-mapping-solution.html)

 Markus Joschko 07-06-2003 07:17 PM

Search for mapping solution

Hi,
stated in a post befor, I'm a java programmer, fascinated about the elegant
way python solves iterations. Maybe you can show me a solution how to map
the following

I have a List:

Name - Number - Costs

lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]

Now I want to have it in a dictionary(name,costs) Should look like
{'fred':'0,60' , 'sam':'1'}

What's an elegant way to do it? I can use a lot of loops, but I assume, that
there is a better way of doing so.

Thanks,
Markus

 Achim Domma 07-06-2003 07:36 PM

Re: Search for mapping solution

"Markus Joschko" <jocsch@phreaker.net> wrote in message
news:be9t66\$2otne\$1@ID-47851.news.dfncis.de...
> Name - Number - Costs
>
> lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]
>
> Now I want to have it in a dictionary(name,costs) Should look like
> {'fred':'0,60' , 'sam':'1'}

I would do it like this:

lines = [['fred','333','0.10'],['sam','444','1'],['fred','333','0.50']]
costs = {}
for name,number,price in lines:
costs[name] = costs.setdefault(name,0)+float(price)
print costs

Achim

 Max M 07-06-2003 07:51 PM

Re: Search for mapping solution

Markus Joschko wrote:

> Hi,
> stated in a post befor, I'm a java programmer, fascinated about the elegant
> way python solves iterations. Maybe you can show me a solution how to map
> the following
>
> I have a List:
>
> Name - Number - Costs
>
> lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]
>
> Now I want to have it in a dictionary(name,costs) Should look like
> {'fred':'0,60' , 'sam':'1'}
>
> What's an elegant way to do it? I can use a lot of loops, but I assume, that
> there is a better way of doing so.

lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]
costs = {}
for name, items, price in lines:
costs[name] = costs.setdefault(name, 0.0) +
float(price.replace(',','.'))

print costs

>>> {'fred': 0.59999999999999998, 'sam': 1.0}

regards Max M

 John J. Lee 07-06-2003 07:55 PM

Re: Search for mapping solution

Markus Joschko <jocsch@phreaker.net> writes:
[...]
> I have a List:
>
> nName - Number - Costs

[...]
> > lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]

[...]

Note that tuples were designed for that sort of 'mini-object' use (and
were not intended primarily as immutable lists).

lines = [('fred','333','0,10'), ('sam','444','1'), ('fred','333','0,50')]

though of course it's no disaster if you end up with a list of
3-element lists instead of 3-tuples, if it's convenient to build the
list with zip or whatever.

John

 Markus Joschko 07-06-2003 08:00 PM

Re: Search for mapping solution

>
> Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on
> win32
>>>> lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]
>>>> d = dict([(x[0], x[2]) for x in lines])
>>>> d

> {'sam': '1', 'fred': '0,50'}

fred should be 0,60. The 3rd column should be summarized.

>
> OK, I'll write and maintain a 1000-line perl program as penance ...
>
> sometimes-concise-is-elegant-too-ly yrs.
>

 Markus Joschko 07-06-2003 08:13 PM

Re: Search for mapping solution

>
> lines = [['fred','333','0.10'],['sam','444','1'],['fred','333','0.50']]
> costs = {}
> for name,number,price in lines:
> costs[name] = costs.setdefault(name,0)+float(price)
> print costs
>

thanks it works. But maybe I can complicate the example a little bit
(because in real world it's more complicated):

What if I every list in lines has 20 or more entries and I have only the
index number to access the name, e.g.

lines = [['elem1','elem2','fred','elem3',.......;'elem
17','333','elem18','0.10'],[...],[...]]

what I want to say: I can't be sure that the name is always on the third
position. That's dynamic. I know it before I parse the list, but
I can't say

for elem1,elem2,name,.... cause it can also be

for elem1,name,elem3 ....

Markus

 Mike C. Fletcher 07-06-2003 09:21 PM

Re: Search for mapping solution

result = {}
for (name, whatever, costs) in lines:
costs = float(number.replace(',','.'))
dict[name] = dict.get( name, 0.0) + costs

(that's untested, but you should get the idea). Note, however, floating
point is generally a poor choice for accounting applications, so you may
want to look into the libraries for fixed-point calculations.

HTH,
Mike

Markus Joschko wrote:

>Hi,
>stated in a post befor, I'm a java programmer, fascinated about the elegant
>way python solves iterations. Maybe you can show me a solution how to map
>the following
>
>I have a List:
>
>Name - Number - Costs
>
>lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]
>
>Now I want to have it in a dictionary(name,costs) Should look like
>{'fred':'0,60' , 'sam':'1'}
>
>What's an elegant way to do it? I can use a lot of loops, but I assume, that
>there is a better way of doing so.
>
>Thanks,
> Markus
>
>

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/

 Bengt Richter 07-06-2003 09:28 PM

Re: Search for mapping solution

On Sun, 06 Jul 2003 21:17:36 +0200, Markus Joschko <jocsch@phreaker.net> wrote:

>Hi,
>stated in a post befor, I'm a java programmer, fascinated about the elegant
>way python solves iterations. Maybe you can show me a solution how to map
>the following
>
>I have a List:
>
>Name - Number - Costs
>
>lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]

>
>Now I want to have it in a dictionary(name,costs) Should look like
>{'fred':'0,60' , 'sam':'1'}

Should same-name costs just be added, and the number just be ignored?
Assuming so, do you actually want the costs in the final dict to be represented
as localized strings, or should they be floating point numbers -- or, should they
be fixed point in effect?
>
>What's an elegant way to do it? I can use a lot of loops, but I assume, that
>there is a better way of doing so.
>

If the names were all different, it would be a snap

>>> lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]
>>> d = dict([(name,cost) for name,num,cost in lines])
>>> d

{'sam': '1', 'fred': '0,50'}

but, your example seems to have further requirements, so maybe:

====< jocsch.py >==============================================
lines = [['fred','333','0,10'],['sam','444','1'],['fred','333','0,50']]

# might want to use locale-sensitive fixed point for currency, but we'll fake it here ;-)
def str2num(s): return ',' in s and int(s.replace(',','')) or 100*int(s) # units of 0,01
def num2str(n): h,u = divmod(abs(n),100); s='-'[:n<0]; return u and '%s%d,%02d'%(s,h,u) or '%s%d'%(s,h)

d={}
for name,num,cost in lines:
cost = str2num(cost) # units of 0,01
d[name] = d.get(name, 0) + cost # accumulate same-name costs in integral units
for name in d.keys(): d[name] = num2str(d[name]) # mixed literal string syntax again

print lines
print d
================================================== =============
Result:

[14:27] C:\pywk\clp>jocsch.py
[['fred', '333', '0,10'], ['sam', '444', '1'], ['fred', '333', '0,50']]
{'sam': '1', 'fred': '0,60'}

A uniform format (i.e., '1,00' instead of '1') would have simplified conversions a little ;-)

Regards,
Bengt Richter

 Alan Kennedy 07-06-2003 09:32 PM

Re: Search for mapping solution

Sean Ross wrote:

> Hi. You've left out the accumulating part of the OP's requirements:

I know :-(

The real temptation I have to resist is deciding to answer someone
question without reading the whole question properly.

I tried to cancel the post as soon as I realised, but it was obviously
too late.

No more posting for me for a while.

--
alan kennedy
-----------------------------------------------------
email alan: http://xhaus.com/mailto/alan

 Markus Joschko 07-07-2003 05:24 PM

Re: Search for mapping solution

Thanks for all the answers. Nice to have such a community.

For me it's really interesting to see all the possible solutions. I learned
some new things in this discussion

Greetings,
Markus

All times are GMT. The time now is 06:02 PM.