Search for mapping solution

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Markus Joschko

    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

    #2
    Re: Search for mapping solution

    "Markus Joschko" <jocsch@phreake r.net> wrote in message
    news:be9t66$2ot [email protected] is.de...[color=blue]
    > 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'}[/color]

    I would do it like this:

    lines = [['fred','333','0 .10'],['sam','444','1'],['fred','333','0 .50']]
    costs = {}
    for name,number,pri ce in lines:
    costs[name] = costs.setdefaul t(name,0)+float (price)
    print costs

    Achim


    Comment

    • Max M

      #3
      Re: Search for mapping solution

      Markus Joschko wrote:
      [color=blue]
      > 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.[/color]

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

      print costs
      [color=blue][color=green][color=darkred]
      >>> {'fred': 0.5999999999999 9998, 'sam': 1.0}[/color][/color][/color]

      regards Max M


      Comment

      • John J. Lee

        #4
        Re: Search for mapping solution

        Markus Joschko <jocsch@phreake r.net> writes:
        [...][color=blue]
        > I have a List:
        >
        > nName - Number - Costs[/color]
        [...][color=blue][color=green]
        > > lines = [['fred','333','0 ,10'],['sam','444','1'],['fred','333','0 ,50']][/color][/color]
        [...]

        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

        Comment

        • Markus Joschko

          #5
          Re: Search for mapping solution

          >[color=blue]
          > Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on
          > win32
          > Type "help", "copyright" , "credits" or "license" for more information.[color=green][color=darkred]
          >>>> lines = [['fred','333','0 ,10'],['sam','444','1'],['fred','333','0 ,50']]
          >>>> d = dict([(x[0], x[2]) for x in lines])
          >>>> d[/color][/color]
          > {'sam': '1', 'fred': '0,50'}[/color]

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

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

          Comment

          • Markus Joschko

            #6
            Re: Search for mapping solution

            >[color=blue]
            > lines = [['fred','333','0 .10'],['sam','444','1'],['fred','333','0 .50']]
            > costs = {}
            > for name,number,pri ce in lines:
            > costs[name] = costs.setdefaul t(name,0)+float (price)
            > print costs
            >[/color]
            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','elem 18','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,nam e,.... cause it can also be

            for elem1,name,elem 3 ....


            Thanks for the answer,
            Markus

            Comment

            • Alan Kennedy

              #7
              Re: Search for mapping solution

              Sean Ross wrote:
              [color=blue]
              > Hi. You've left out the accumulating part of the OP's requirements:[/color]

              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
              -----------------------------------------------------
              check http headers here: http://xhaus.com/headers
              email alan: http://xhaus.com/mailto/alan

              Comment

              • Bengt Richter

                #8
                Re: Search for mapping solution

                On Sun, 06 Jul 2003 21:17:36 +0200, Markus Joschko <jocsch@phreake r.net> wrote:
                [color=blue]
                >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']][/color]
                [color=blue]
                >
                >Now I want to have it in a dictionary(name ,costs) Should look like
                >{'fred':'0,6 0' , 'sam':'1'}[/color]
                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?[color=blue]
                >
                >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.
                >[/color]
                If the names were all different, it would be a snap
                [color=blue][color=green][color=darkred]
                >>> lines = [['fred','333','0 ,10'],['sam','444','1'],['fred','333','0 ,50']]
                >>> d = dict([(name,cost) for name,num,cost in lines])
                >>> d[/color][/color][/color]
                {'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),1 00); 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>joc sch.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

                Comment

                • Mike C. Fletcher

                  #9
                  Re: Search for mapping solution

                  result = {}
                  for (name, whatever, costs) in lines:
                  costs = float(number.re place(',','.'))
                  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:
                  [color=blue]
                  >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,6 0' , '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
                  >
                  >[/color]
                  _______________ _______________ _________
                  Mike C. Fletcher
                  Designer, VR Plumber, Coder





                  Comment

                  • Markus Joschko

                    #10
                    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

                    Comment

                    • Martin Maney

                      #11
                      Re: Search for mapping solution

                      I dedicate this monument to Alan Kennedy, without whom I would probably
                      never have tried to compress things so. :-)

                      Sean Ross <sross@connectm ail.carleton.ca > wrote:[color=blue]
                      > lines = [['fred','333','0 .10'],['sam','444','1'],['fred','333','0 .50']]
                      > costs = {}
                      > # nearly identical to Achim's solution, but with a list comp.
                      > [costs.__setitem __(name, costs.get(name, 0)+float(price) )
                      > for name, number, price in lines]
                      > print costs
                      > # outputs: {'sam': 1.0, 'fred': 0.60}[/color]

                      It isn't really one line though, is it? For truly cryptic terseness
                      you want to swing functional (I shall adopt your interpretation of the
                      third element although seeing it as a list of integers would have
                      allowed for additional functional yumminess):
                      [color=blue][color=green][color=darkred]
                      >>> lines = [['fred','333','0 .10'],['sam','444','1'],['fred','333','0 .50']]
                      >>> reduce(lambda d,x: d.update({x[0]: d.get(x[0],0.0) + float(x[2])}) or d, [{}] + lines)[/color][/color][/color]
                      {'fred': 0.5999999999999 9998, 'sam': 1.0}

                      Mind you, I normally despise the whole one-liner phenomenon, which
                      makes me almost pleased about the inelegant necessity of that 'or d' -
                      blame it on either update's lack of a return value or lambda's
                      emasculation. But as I've been working my way through SICP as this
                      summer's project, it certainly seems odd. :-/

                      --
                      automation: replacing what works with something that almost works,
                      but which is faster and cheaper. - attributed to Roger Needham

                      Comment

                      Working...