undo a dictionary

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

    undo a dictionary

    I found code to undo a dictionary association.

    def undict(dd, name_space=glob als()):
    for key, value in dd.items():
    exec "%s = %s" % (key, repr(value)) in name_space

    So if i run
    >>dx= { 'a':1, 'b': 'B'}
    >>undict(dx)
    I get
    >>print A, B
    1 B

    Here, a=1 and b='B'

    This works well enough for simple tasks and I understand the role of
    globals() as the default names space, but creating local variables is
    a problem. Also having no output arguemtns to undict() seems
    counterintuitiv e. Also, the function fails if the key has spaces or
    operand characters (-,$,/,%). Finally I know I will have cases where
    not clearing (del(a,b)) each key-value pair might create problems in a
    loop.

    So I wonder if anyone has more elegant code to do the task that is
    basically the opposite of creating a dictionary from a set of
    globally assigned variables. And for that matter a way to create a
    dictionary from a set of variables (local or global). Note I am not
    simply doing and undoing dict(zip(keys,v alues))
  • Kay Schluehr

    #2
    Re: undo a dictionary

    On 30 Jul., 16:51, mmm <mdbol...@gmail .comwrote:
    I found code to undo a dictionary association.
    >
    def undict(dd, name_space=glob als()):
    for key, value in dd.items():
    exec "%s = %s" % (key, repr(value)) in name_space
    >
    So if i run
    >
    >dx= { 'a':1, 'b': 'B'}
    >undict(dx)
    >
    I get>>print A, B
    >
    1 B
    >
    Here, a=1 and b='B'
    >
    This works well enough for simple tasks and I understand the role of
    globals() as the default names space, but creating local variables is
    a problem.
    Python is lexically scoped. You can't create locals at runtime.
    Also having no output arguemtns to undict() seems
    counterintuitiv e. Also, the function fails if the key has spaces or
    operand characters (-,$,/,%).
    Python names can't have punctuation with the exception of underscores.
    Finally I know I will have cases where
    not clearing (del(a,b)) each key-value pair might create problems in a
    loop.
    >
    So I wonder if anyone has more elegant code to do the task that is
    basically the opposite of creating a dictionary from a set of
    globally assigned variables. And for that matter a way to create a
    dictionary from a set of variables (local or global). Note I am not
    simply doing and undoing dict(zip(keys,v alues))
    May I ask what's wrong with having namespaces in a language?


    Comment

    • bockman@virgilio.it

      #3
      Re: undo a dictionary

      On 30 Lug, 16:51, mmm <mdbol...@gmail .comwrote:
      I found code to undo a dictionary association.
      >
      def undict(dd, name_space=glob als()):
          for key, value in dd.items():
              exec "%s = %s" % (key, repr(value)) in name_space
      >
      So if i run
      >
      >dx= { 'a':1, 'b': 'B'}
      >undict(dx)
      >
      I get>>print A, B
      >
      1 B
      >
      Here,  a=1 and b='B'
      >
      This works well enough for simple tasks and I understand the role of
      globals() as the default names space, but creating local variables is
      a problem. Also having no output arguemtns to undict() seems
      counterintuitiv e.  Also, the function fails if the key has spaces or
      operand characters (-,$,/,%).  Finally I know I will have cases where
      not clearing (del(a,b)) each key-value pair might create problems in a
      loop.
      >
      So I wonder if anyone has more elegant code to do the task that is
      basically the opposite of creating a dictionary from a set of
      globally assigned variables.  And for that matter a way to create a
      dictionary from a set of variables (local or global).  Note I am not
      simply doing and  undoing dict(zip(keys,v alues))

      Maybe you can use objects as pseudo name spaces and do sommething like
      this:
      >>class Scope(object):
      def dict(self):
      res = dict()
      for k, v in self.__dict__.i tems(): res[k] = v
      return res
      def undict(self, dict):
      for k,v in dict.items():
      setattr(self, k, v )

      >>myscope = Scope()
      >>myscope.undic t(dict(A=1, B=2))
      >>myscope.A
      1
      >>myscope.B
      2
      >>myscope.dict( )
      {'A': 1, 'B': 2}
      >>>

      Ciao
      ------
      FB


      Comment

      • Terry Reedy

        #4
        Re: undo a dictionary



        mmm wrote:
        I found code to undo a dictionary association.
        >
        def undict(dd, name_space=glob als()):
        for key, value in dd.items():
        exec "%s = %s" % (key, repr(value)) in name_space
        You are not undoing anything. You are updating globals() from another
        dict. But why repr(value)? Without that, globals().updat e(dd) would
        work. In 2.6?/3.0, replace 'dd' with '{a:b for a,b in dd.items()}

        dd = { 'a':1, 'b': 'B'}
        globals().updat e({a:b for a,b in dd.items()})
        print(a,b)
        # 1,B
        >>>dx= { 'a':1, 'b': 'B'}
        >>>undict(dx)
        >
        I get
        >>>print A, B
        1 B
        >
        Here, a=1 and b='B'
        Don't fake interactive output. You would have to "print a,b". Above
        gives a NameError.
        This works well enough for simple tasks and I understand the role of
        globals() as the default names space, but creating local variables is
        a problem.
        Within functions, yes. Just access the values in the dict.
        Also having no output arguemtns to undict() seems
        counterintuitiv e.
        In Python, this is standard for functions that mutate.
        Also, the function fails if the key has spaces or
        operand characters (-,$,/,%).
        Exec is tricky. Most people hardly ever use it.
        Finally I know I will have cases where
        not clearing (del(a,b)) each key-value pair might create problems in a
        loop.
        You cannot mutate a dict while iterating through it.
        So I wonder if anyone has more elegant code to do the task that is
        basically the opposite of creating a dictionary from a set of
        globally assigned variables.
        See above.
        And for that matter a way to create a
        dictionary from a set of variables (local or global).
        You have to be more specific: there are {} displays and dict(args) call
        and other methods. Read the manual.

        tjr

        Comment

        • mmm

          #5
          Re: undo a dictionary

          And for that matter a way to create a
          dictionary from a set of variables (local or global).
          >
          You have to be more specific: there are {} displays and dict(args) call
          and other methods.  Read the manual.
          My desire is to take a set of data items in an alpha-numeric range and
          oput them into a dictionary

          i.e.,
          x1=1
          x2=20
          x3=33

          to yield the dictionary

          { 'x1':1, 'x2':20, 'x3':33 }

          without having to type in as above but instead invoke a function

          maybe with syntax of

          dd=make_dict('x 1--x99')

          Comment

          • Gabriel Genellina

            #6
            Re: undo a dictionary

            En Wed, 30 Jul 2008 16:14:31 -0300, mmm <mdboldin@gmail .comescribi�:
            And for that matter a way to create a
            dictionary from a set of variables (local or global).
            >>
            >You have to be more specific: there are {} displays and dict(args) call
            >and other methods.  Read the manual.
            >
            My desire is to take a set of data items in an alpha-numeric range and
            oput them into a dictionary
            >
            i.e.,
            x1=1
            x2=20
            x3=33
            >
            to yield the dictionary
            >
            { 'x1':1, 'x2':20, 'x3':33 }
            >
            without having to type in as above but instead invoke a function
            dict(x1=1, x2=20, x3=33) does the same thing.

            Or, do you mean you already have those names and values, perhaps mixed
            with a lot more names, and want to extract only those starting with "x"
            and following with a number?

            result = {}
            for name, value in vars(): # or locals().items( ), or globals().items (), or
            vars(some_modul e)
            if name[0]=='x' and name[1:].isdigit():
            result[name] = value

            --
            Gabriel Genellina

            Comment

            • castironpi

              #7
              Re: undo a dictionary

              On Jul 30, 8:07 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.a r>
              wrote:
              En Wed, 30 Jul 2008 16:14:31 -0300, mmm <mdbol...@gmail .comescribi :
              >
              >
              >
              And for that matter a way to create a
              dictionary from a set of variables (local or global).
              >
              You have to be more specific: there are {} displays and dict(args) call
              and other methods.  Read the manual.
              >
              My desire is to take a set of data items in an alpha-numeric range and
              oput them into a dictionary
              >
              i.e.,
              x1=1
              x2=20
              x3=33
              >
              to yield  the dictionary
              >
              { 'x1':1, 'x2':20, 'x3':33 }
              >
              without having to type in as above but instead invoke a function
              >
              dict(x1=1, x2=20, x3=33) does the same thing.
              >
              Or, do you mean you already have those names and values, perhaps mixed  
              with a lot more names, and want to extract only those starting with "x"  
              and following with a number?
              >
              result = {}
              for name, value in vars(): # or locals().items( ), or globals().items (), or  
              vars(some_modul e)
                 if name[0]=='x' and name[1:].isdigit():
                   result[name] = value
              >
              --
              Gabriel Genellina
              You can also use a blank class instance, and update its __dict__
              member with the dictionary you design.
              >>class A: pass
              ...
              >>d= { 'x1': 0, 'x2': set( ) }
              >>A.__dict__
              {'__module__': '__main__', '__doc__': None}
              >>A.__dict__.up date( d )
              >>A.__dict__
              {'x2': set([]), '__module__': '__main__', 'x1': 0, '__doc__': None}
              >>A.x1
              0
              >>A.x2
              set([])
              >>>
              I agree that locals( ) shouldn't necessarily be read-only, and I
              believe it would extend the power of Python if it weren't.

              Comment

              • mmm

                #8
                Re: undo a dictionary

                Gabriel,

                I meant the latter, so this helps
                Or, do you mean you already have those names and values, perhaps mixed  
                with a lot more names, and want to extract only those starting with "x"  
                and following with a number?
                >
                result = {}
                for name, value in vars(): # or locals().items( ), or globals().items (), or  
                vars(some_modul e)
                   if name[0]=='x' and name[1:].isdigit():
                     result[name] = value
                But I got an error with 'for name, value in vars():'
                RuntimeError: dictionary changed size during iteration

                I think globals() has the same problem, but globals.items() works. I
                will need to read the docs to learn why '.items()' works but the
                changing global dictionary problem makes sense. I assume I need to
                use a non dynamic created list.

                Sometimes I get the error about 'too many variables to unpack' (can
                not consistently repeat the error however)

                In any event, thanks for the suggestions, everyone.

                Using a blank class for unpacking the dictionary makes the most sense,
                for safety sake.
                So you know the general issue is I want to switch between using
                dictionaries for storing data items and simple variable names for
                writing equations/formulas, So (a) and (b) below are preferred to (c)
                for readability

                (a) straight forward equation

                y = b0 + b1*Age + b2*Size

                (b) Class version

                y = b0 + b1*x.Age + b2*x.Size

                (c) Dictionary version

                y = b0 + b1*dd.get('Age' ) + b2*dd.get('Size ')

                Comment

                Working...