Updating python dictionary

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • andyhume@gmail.com

    Updating python dictionary

    Hello...

    I have a dict of key/values and I want to change the keys in it, based
    on another mapping dictionary. An example follows:

    MAPPING_DICT = {
    'a': 'A',
    'b': 'B',
    }

    my_dict = {
    'a': '1',
    'b': '2'
    }

    I want the finished my_dict to look like:

    my_dict = {
    'A': '1',
    'B': '2'
    }

    Whereby the keys in the original my_dict have been swapped out for the
    keys mapped in MAPPING_DICT.

    Is there a clever way to do this, or should I loop through both,
    essentially creating a brand new dict?

    Cheers,
    Andy.
  • Marc 'BlackJack' Rintsch

    #2
    Re: Updating python dictionary

    On Sun, 07 Sep 2008 14:51:32 -0700, andyhume@gmail. com wrote:
    MAPPING_DICT = {
    'a': 'A',
    'b': 'B',
    }
    >
    my_dict = {
    'a': '1',
    'b': '2'
    }
    >
    I want the finished my_dict to look like:
    >
    my_dict = {
    'A': '1',
    'B': '2'
    }
    >
    Whereby the keys in the original my_dict have been swapped out for the
    keys mapped in MAPPING_DICT.
    >
    Is there a clever way to do this, or should I loop through both,
    essentially creating a brand new dict?
    You only have to loop through `my_dict`:

    In [187]: %cpaste
    Pasting code; enter '--' alone on the line to stop.
    :MAPPING_DICT = {
    : 'a': 'A',
    : 'b': 'B',
    :}
    :
    :my_dict = {
    : 'a': '1',
    : 'b': '2'
    :}
    :--

    In [188]: dict((MAPPING_D ICT[k], v) for k, v in my_dict.iterite ms())
    Out[188]: {'A': '1', 'B': '2'}

    Ciao,
    Marc 'BlackJack' Rintsch

    Comment

    • MK Bernard

      #3
      Re: Updating python dictionary

      On Sep 7, 2:51 pm, "andyh...@gmail .com" <andyh...@gmail .comwrote:
      Hello...
      >
      I have a dict of key/values and I want to change the keys in it, based
      on another mapping dictionary. An example follows:
      >
      MAPPING_DICT = {
          'a': 'A',
          'b': 'B',
      >
      }
      >
      my_dict = {
          'a': '1',
          'b': '2'
      >
      }
      >
      I want the finished my_dict to look like:
      >
      my_dict = {
          'A': '1',
          'B': '2'
      >
      }
      >
      Whereby the keys in the original my_dict have been swapped out for the
      keys mapped in MAPPING_DICT.
      >
      Is there a clever way to do this, or should I loop through both,
      essentially creating a brand new dict?
      >
      Cheers,
      Andy.
      You could accomplish this with something similar to the following:
      new_dict = {}
      for x in MAPPING_DICT.ke ys():
      if x in my_dict.keys():
      new_dict[MAPPING_DICT[x]] = my_dict[x]

      Although there is probably a better solution to the problem your
      having. Perhaps more details could help us lead in you the right
      direction?

      Cheers, MK

      Comment

      • Fredrik Lundh

        #4
        Re: Updating python dictionary

        andyhume@gmail. com wrote:
        Is there a clever way to do this, or should I loop through both,
        essentially creating a brand new dict?
        since none of your dictionaries contain the keys you want in the final
        dictionary, creating a brand new dict sounds pretty clever to me.

        </F>

        Comment

        • James Mills

          #5
          Re: Updating python dictionary

          Hi,

          There is "never" a "clever" way
          of doing anything, but:

          $ cat test.py
          MAPPING_DICT = {'a': 'A','b': 'B',}
          my_dict = {'a': '1','b': '2'}
          my_dict = dict((MAPPING_D ICT[k], my_dict[k]) for k in my_dict)
          print my_dict
          $ python test.py
          {'A': '1', 'B': '2'}
          $

          That should do the trick.

          cheers
          James

          On Mon, Sep 8, 2008 at 7:51 AM, andyhume@gmail. com <andyhume@gmail .comwrote:
          Hello...
          >
          I have a dict of key/values and I want to change the keys in it, based
          on another mapping dictionary. An example follows:
          >
          MAPPING_DICT = {
          'a': 'A',
          'b': 'B',
          }
          >
          my_dict = {
          'a': '1',
          'b': '2'
          }
          >
          I want the finished my_dict to look like:
          >
          my_dict = {
          'A': '1',
          'B': '2'
          }
          >
          Whereby the keys in the original my_dict have been swapped out for the
          keys mapped in MAPPING_DICT.
          >
          Is there a clever way to do this, or should I loop through both,
          essentially creating a brand new dict?
          >
          Cheers,
          Andy.
          --

          >


          --
          --
          -- "Problems are solved by method"

          Comment

          • Gabriel Genellina

            #6
            Re: Updating python dictionary

            En Sun, 07 Sep 2008 18:51:32 -0300, andyhume@gmail. com <andyhume@gmail .comescribió:
            I have a dict of key/values and I want to change the keys in it, based
            on another mapping dictionary. An example follows:
            >
            MAPPING_DICT = {
            'a': 'A',
            'b': 'B',
            }
            >
            my_dict = {
            'a': '1',
            'b': '2'
            }
            >
            I want the finished my_dict to look like:
            >
            my_dict = {
            'A': '1',
            'B': '2'
            }
            >
            Whereby the keys in the original my_dict have been swapped out for the
            keys mapped in MAPPING_DICT.
            >
            Is there a clever way to do this, or should I loop through both,
            essentially creating a brand new dict?
            Exactly. You can do that in one pass:

            my_new_dict = dict((MAPPING_D ICT[k],v) for (k,v) in my_dict.iterite ms())

            That's enough if MAPPING_DICT always contains all the keys. If you want to keep old keys that aren't in MAPPING_DICT unchanged, use MAPPING_DICT.ge t(k,k) instead. Other corner cases include many-to-one mappings, and incomplete mappings where a replacement key is also an unmapped old key.

            --
            Gabriel Genellina

            Comment

            • John Machin

              #7
              Re: Updating python dictionary

              On Sep 8, 7:51 am, "andyh...@gmail .com" <andyh...@gmail .comwrote:
              Hello...
              >
              I have a dict of key/values and I want to change the keys in it, based
              on another mapping dictionary. An example follows:
              >
              MAPPING_DICT = {
                  'a': 'A',
                  'b': 'B',
              >
              }
              >
              my_dict = {
                  'a': '1',
                  'b': '2'
              >
              }
              >
              I want the finished my_dict to look like:
              >
              my_dict = {
                  'A': '1',
                  'B': '2'
              >
              }
              >
              Whereby the keys in the original my_dict have been swapped out for the
              keys mapped in MAPPING_DICT.
              >
              Is there a clever way to do this, or should I loop through both,
              essentially creating a brand new dict?
              >
              Is this homework?

              There seems to be an implicit assumption in the answers so far that
              your mapping is a 1:1 mapping of all possible input keys.

              If it doesn't include all possible input keys, answers will crash with
              a KeyError. If there are any many:1 elements in the mapping (for
              example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
              in some checks for this.

              Comment

              • James Mills

                #8
                Re: Updating python dictionary

                On Mon, Sep 8, 2008 at 8:37 AM, John Machin <sjmachin@lexic on.netwrote:
                Is this homework?
                I hope it's not - or I'll be quite annoyed :)
                There seems to be an implicit assumption in the answers so far that
                your mapping is a 1:1 mapping of all possible input keys.
                >
                If it doesn't include all possible input keys, answers will crash with
                a KeyError. If there are any many:1 elements in the mapping (for
                example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
                in some checks for this.
                You are quite right! But then he/she didn't
                ask for this right ? :)

                cheers
                James

                --
                --
                -- "Problems are solved by method"

                Comment

                • John Machin

                  #9
                  Re: Updating python dictionary

                  On Sep 8, 8:42 am, "James Mills" <prolo...@short circuit.net.auw rote:
                  On Mon, Sep 8, 2008 at 8:37 AM, John Machin <sjmac...@lexic on.netwrote:
                  There seems to be an implicit assumption in the answers so far that
                  your mapping is a 1:1 mapping of all possible input keys.
                  >
                  If it doesn't include all possible input keys, answers will crash with
                  a KeyError. If there are any many:1 elements in the mapping (for
                  example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
                  in some checks for this.
                  >
                  You are quite right! But then he/she didn't
                  ask for this right ? :)
                  >
                  What do you mean by "this right"? Perhaps the Divine Right of OPs,
                  managers, examiners, business analysts, etc never to give a complete
                  spec up front and never to contemplate the consequences of Murphy's
                  Law?

                  Comment

                  • Steven D'Aprano

                    #10
                    Re: Updating python dictionary

                    On Sun, 07 Sep 2008 15:59:52 -0700, John Machin wrote:
                    On Sep 8, 8:42 am, "James Mills" <prolo...@short circuit.net.auw rote:
                    >On Mon, Sep 8, 2008 at 8:37 AM, John Machin <sjmac...@lexic on.net>
                    >wrote:
                    >
                    There seems to be an implicit assumption in the answers so far that
                    your mapping is a 1:1 mapping of all possible input keys.
                    >>
                    If it doesn't include all possible input keys, answers will crash
                    with a KeyError. If there are any many:1 elements in the mapping (for
                    example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
                    in some checks for this.
                    >>
                    >You are quite right! But then he/she didn't ask for this right ? :)
                    >>
                    >>
                    What do you mean by "this right"? Perhaps the Divine Right of OPs,
                    managers, examiners, business analysts, etc never to give a complete
                    spec up front and never to contemplate the consequences of Murphy's Law?

                    I *think* that what James Mills meant was:

                    "But then he/she didn't ask for this comma right?"



                    --
                    Steven

                    Comment

                    • James Mills

                      #11
                      Re: Updating python dictionary

                      On Mon, Sep 8, 2008 at 8:59 AM, John Machin <sjmachin@lexic on.netwrote:
                      What do you mean by "this right"? Perhaps the Divine Right of OPs,
                      managers, examiners, business analysts, etc never to give a complete
                      spec up front and never to contemplate the consequences of Murphy's
                      Law?
                      Now you're being silly.

                      --
                      --
                      -- "Problems are solved by method"

                      Comment

                      • MK Bernard

                        #12
                        Re: Updating python dictionary

                        On Sep 7, 3:37 pm, John Machin <sjmac...@lexic on.netwrote:
                        On Sep 8, 7:51 am, "andyh...@gmail .com" <andyh...@gmail .comwrote:
                        >
                        >
                        >
                        Hello...
                        >
                        I have a dict of key/values and I want to change the keys in it, based
                        on another mapping dictionary. An example follows:
                        >
                        MAPPING_DICT = {
                            'a': 'A',
                            'b': 'B',
                        >
                        }
                        >
                        my_dict = {
                            'a': '1',
                            'b': '2'
                        >
                        }
                        >
                        I want the finished my_dict to look like:
                        >
                        my_dict = {
                            'A': '1',
                            'B': '2'
                        >
                        }
                        >
                        Whereby the keys in the original my_dict have been swapped out for the
                        keys mapped in MAPPING_DICT.
                        >
                        Is there a clever way to do this, or should I loop through both,
                        essentially creating a brand new dict?
                        >
                        Is this homework?
                        >
                        There seems to be an implicit assumption in the answers so far that
                        your mapping is a 1:1 mapping of all possible input keys.
                        >
                        If it doesn't include all possible input keys, answers will crash with
                        a KeyError. If there are any many:1 elements in the mapping (for
                        example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
                        in some checks for this.
                        Thats exactly why I did an explicit check in my post, so as to make
                        sure that such a collision could not occur. It would seem that
                        something along what I posted would be safer, if less elegant, than
                        the others.
                        Cheers, MK

                        Comment

                        • John Machin

                          #13
                          Re: Updating python dictionary

                          On Sep 8, 10:47 am, MK Bernard <mkbernard....@ gmail.comwrote:
                          On Sep 7, 3:37 pm, John Machin <sjmac...@lexic on.netwrote:
                          >
                          >
                          >
                          >
                          >
                          On Sep 8, 7:51 am, "andyh...@gmail .com" <andyh...@gmail .comwrote:
                          >
                          Hello...
                          >
                          I have a dict of key/values and I want to change the keys in it, based
                          on another mapping dictionary. An example follows:
                          >
                          MAPPING_DICT = {
                              'a': 'A',
                              'b': 'B',
                          >
                          }
                          >
                          my_dict = {
                              'a': '1',
                              'b': '2'
                          >
                          }
                          >
                          I want the finished my_dict to look like:
                          >
                          my_dict = {
                              'A': '1',
                              'B': '2'
                          >
                          }
                          >
                          Whereby the keys in the original my_dict have been swapped out for the
                          keys mapped in MAPPING_DICT.
                          >
                          Is there a clever way to do this, or should I loop through both,
                          essentially creating a brand new dict?
                          >
                          Is this homework?
                          >
                          There seems to be an implicit assumption in the answers so far that
                          your mapping is a 1:1 mapping of all possible input keys.
                          >
                          If it doesn't include all possible input keys, answers will crash with
                          a KeyError. If there are any many:1 elements in the mapping (for
                          example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
                          in some checks for this.
                          >
                          Thats exactly why I did an explicit check in my post, so as to make
                          sure that such a collision could not occur. It would seem that
                          something along what I posted would be safer, if less elegant, than
                          the others.
                          I noted two problems:
                          (1) not covering all input keys: your code explicitly sweeps this
                          problem under the carpet, and does it laboriously ...
                          if x in my_dict.keys():
                          instead of
                          if x in my_dict:
                          (2) not a 1:1 mapping -- for example, 'a' and 'b' both map to 'A' (the
                          only "collision" that I can see), but you don't address that.

                          Here's some code which attempts to cover the bases:

                          new_dict = {}
                          for key in my_dict:
                          if key not in MAPPING_DICT:
                          raise NoMapError('bla h %r' % key)
                          else:
                          new_key = MAPPING_DICT[key]
                          if new_key in new_dict:
                          raise ManyToOneError( 'gurgle %r waffle %r' % (key, new_key))
                          else:
                          new_dict[new_key] = my_dict[key]

                          Having considered what is actually required under the checked-for
                          conditions, one or both raise statements may be replaced by other
                          code, and then simplified e.g. the first 4 lines in the loop may end
                          up being replaced by
                          new_key = MAPPING_DICT.ge t(key, key)
                          as already suggested by one respondent.

                          Note that useful use-cases for any variety of this key-change exercise
                          may have many more items in MAPPING_DICT than there are in my_dict (a
                          big language dictionary and a few fragments of text to be
                          "translated "), or vice versa (a small synonym dictionary (color ->
                          colour, center -centre) and a big input to be "standardis ed") so
                          it's a good idea to inquire which is likely to be the smaller and
                          iterate over that if the requirements permit it.

                          Comment

                          • John Machin

                            #14
                            Re: Updating python dictionary

                            On Sep 8, 9:14 am, "James Mills" <prolo...@short circuit.net.auw rote:
                            On Mon, Sep 8, 2008 at 8:59 AM, John Machin <sjmac...@lexic on.netwrote:
                            What do you mean by "this right"? Perhaps the Divine Right of OPs,
                            managers, examiners, business analysts, etc never to give a complete
                            spec up front and never to contemplate the consequences of Murphy's
                            Law?
                            >
                            Now you're being silly.
                            >
                            Only in so far as I followed the habit of OPs and suchlike by using
                            "never" instead of "rarely".

                            Comment

                            • andyhume@gmail.com

                              #15
                              Re: Updating python dictionary

                              On Sep 8, 10:20 am, John Machin <sjmac...@lexic on.netwrote:
                              On Sep 8, 10:47 am, MK Bernard <mkbernard....@ gmail.comwrote:
                              >
                              >
                              >
                              On Sep 7, 3:37 pm, John Machin <sjmac...@lexic on.netwrote:
                              >
                              On Sep 8, 7:51 am, "andyh...@gmail .com" <andyh...@gmail .comwrote:
                              >
                              Hello...
                              >
                              I have a dict of key/values and I want to change the keys in it, based
                              on another mapping dictionary. An example follows:
                              >
                              MAPPING_DICT = {
                                  'a': 'A',
                                  'b': 'B',
                              >
                              }
                              >
                              my_dict = {
                                  'a': '1',
                                  'b': '2'
                              >
                              }
                              >
                              I want the finished my_dict to look like:
                              >
                              my_dict = {
                                  'A': '1',
                                  'B': '2'
                              >
                              }
                              >
                              Whereby the keys in the original my_dict have been swapped out for the
                              keys mapped in MAPPING_DICT.
                              >
                              Is there a clever way to do this, or should I loop through both,
                              essentially creating a brand new dict?
                              >
                              Is this homework?
                              >
                              There seems to be an implicit assumption in the answers so far that
                              your mapping is a 1:1 mapping of all possible input keys.
                              >
                              If it doesn't include all possible input keys, answers will crash with
                              a KeyError. If there are any many:1 elements in the mapping (for
                              example, {'a': 'A', 'b': 'A'}), lossage happens. You may wish to code
                              in some checks for this.
                              >
                              Thats exactly why I did an explicit check in my post, so as to make
                              sure that such a collision could not occur. It would seem that
                              something along what I posted would be safer, if less elegant, than
                              the others.
                              >
                              I noted two problems:
                              (1) not covering all input keys: your code explicitly sweeps this
                              problem under the carpet, and does it laboriously ...
                                  if x in my_dict.keys():
                              instead of
                                  if x in my_dict:
                              (2) not a 1:1 mapping -- for example, 'a' and 'b' both map to 'A' (the
                              only "collision" that I can see), but you don't address that.
                              >
                              Here's some code which attempts to cover the bases:
                              >
                              new_dict = {}
                              for key in my_dict:
                                  if key not in MAPPING_DICT:
                                      raise NoMapError('bla h %r' % key)
                                  else:
                                      new_key = MAPPING_DICT[key]
                                  if new_key in new_dict:
                                      raise ManyToOneError( 'gurgle %r waffle %r' % (key, new_key))
                                  else:
                                      new_dict[new_key] = my_dict[key]
                              >
                              Having considered what is actually required under the checked-for
                              conditions, one or both raise statements may be replaced by other
                              code, and then simplified e.g. the first 4 lines in the loop may end
                              up being replaced by
                                  new_key = MAPPING_DICT.ge t(key, key)
                              as already suggested by one respondent.
                              >
                              Note that useful use-cases for any variety of this key-change exercise
                              may have many more items in MAPPING_DICT than there are in my_dict (a
                              big language dictionary and a few fragments of text to be
                              "translated "), or vice versa (a small synonym dictionary (color ->
                              colour, center -centre) and a big input to be "standardis ed") so
                              it's a good idea to inquire which is likely to be the smaller and
                              iterate over that if the requirements permit it.
                              In the interests of academia (although this isn't homework :)) I'll
                              answer some of those questions:

                              - Yes, the mapping dict doesn't necessarily have the same number of
                              entries as the my_dict. It may have less than it or more than it.
                              - There will never be dupes of key or value in the mapping. Though
                              there maybe in my_dict.

                              And, for extra credit, it may be useful to be able to 'translate' the
                              my_dict back again using the same mapping_dict. ie, using the values
                              in mapping dict as the new keys in my_dict, and the keys as the new
                              values.

                              Andy.

                              Comment

                              Working...