Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Creating variables from dicts

5 views
Skip to first unread message

vsoler

unread,
Feb 23, 2010, 3:53:14 PM2/23/10
to
Hi,

I have two dicts

n={'a', 'm', 'p'}
v={1,3,7}

and I'd like to have

a=1
m=3
p=7

that is, creating some variables.

How can I do this?

Arnaud Delobelle

unread,
Feb 23, 2010, 4:10:14 PM2/23/10
to
vsoler <vicent...@gmail.com> writes:

> Hi,
>
> I have two dicts
>
> n={'a', 'm', 'p'}
> v={1,3,7}

These are sets, not dicts.

> and I'd like to have
>
> a=1
> m=3
> p=7

As sets are unordered, you may as well have

a = 3
m = 7
p = 1

or any other permutation. You need some sequences instead. E.g.

n = ['a', 'm', 'p']
v = (1, 3, 7)

Then you can do:

for name, value in zip(n, v):
globals()[name] = value

After this the names, 'a', 'm' and 'p' will be bound to the values you
want in the global namespace. However, it is almost always a bad idea
to do this. Can you explain why you need to do this?

--
Arnaud

Hai Vu

unread,
Feb 23, 2010, 4:21:36 PM2/23/10
to

I think you meant to use the square brackets [ ] instead of the curly
ones { } to define the list:

>>> n = ['a', 'b', 'c']
>>> v = [3, 5, 7]
>>> for x, y in zip(n, v):
... exec '%s=%d' % (x, y)
...
>>> a
3
>>> b
5
>>> c
7

---
The key is the use of the exec statement, which executes the strings
"a=3", "b=5", ... as if they are python statements.

MRAB

unread,
Feb 23, 2010, 4:31:48 PM2/23/10
to pytho...@python.org
vsoler wrote:
> Hi,
>
> I have two dicts
>
> n={'a', 'm', 'p'}
> v={1,3,7}
>
Those aren't dicts, they're sets.

> and I'd like to have
>
> a=1
> m=3
> p=7
>
> that is, creating some variables.
>
> How can I do this?

The real question is not how, but why?

Anyway, assuming you want them to be global variables:

globals().update(dict(zip(n, v)))

On my machine the variables didn't get the correct values because, as I
said, 'n' and 'v' are sets, so the order of the members is arbitrary.

Luis M. González

unread,
Feb 23, 2010, 5:56:30 PM2/23/10
to

You are probably coming from another language and you're not used to
python's data structures.
If you want a list of items, you use tuples or lists. Examples:

('a', 'm', 'p') ---> this is a tuple, and it's made with
parenthesis ()
['a', 'm', 'p'] ---> this is a list, and it's made with brackets
[]

Check the documentation to see the difference between tuples and
lists.
For now, lets just use lists and forget about tuples...
Now if you want a sequence of items ordered a key + value pairs, use a
dictionary, as follows:

{'name': 'joe', 'surname': 'doe', 'age': 21} ---> this is a dict,
and it's made with curly braces {}.

Curly braces are also used to create sets, but you don't need them now
(check the documentation to learn more about sets).
So going back to your question, you should have two lists, as follows:

n = ['a', 'm', 'p']
v = [1,3,7] --> note that I used brackets [], not curly
braces {}.

And now you can build a dict formed by the keys in "n" and the values
in "v":

myDict = {} --> this is an new empty dictionary
for k,v in zip(n,v):
myDict[k] = v

This results in this dictionary: {'a': 1, 'p': 7, 'm': 3}.

Hope this helps...
Luis

Luis M. González

unread,
Feb 23, 2010, 6:41:16 PM2/23/10
to

By the way, if you want the variables inside myDict to be free
variables, you have to add them to the local namespace.
The local namespace is also a dictionary "locals()".
So you can update locals as follows:

locals().update( myDictionary )

This way, all the key-value pairs inside myDict become free variables.
Wich is the same as declaring them as follows:

a = 1
p = 7

etc...

Luis

Tim Chase

unread,
Feb 23, 2010, 6:41:37 PM2/23/10
to "Luis M. González", pytho...@python.org
Luis M. Gonz�lez wrote:
> If you want a list of items, you use tuples or lists. Examples:
>
> ('a', 'm', 'p') ---> this is a tuple, and it's made with
> parenthesis ()

Actually, a tuple is made with commas...the parens are just there
to clarify the order of operations and make it easier to read :)

>>> x = 1,2,3
>>> x
(1, 2, 3)

-tkc

Steven D'Aprano

unread,
Feb 23, 2010, 8:41:26 PM2/23/10
to
On Tue, 23 Feb 2010 15:41:16 -0800, Luis M. González wrote:

> By the way, if you want the variables inside myDict to be free
> variables, you have to add them to the local namespace. The local
> namespace is also a dictionary "locals()". So you can update locals as
> follows:
>
> locals().update( myDictionary )

No you can't. Try it inside a function.


--
Steven

Luis M. González

unread,
Feb 23, 2010, 10:47:22 PM2/23/10
to
On Feb 23, 10:41 pm, Steven D'Aprano

Sure. Inside a function I would use globals() instead.
Although I don't know if it would be a good practice...

Luis

Steven D'Aprano

unread,
Feb 23, 2010, 11:15:31 PM2/23/10
to

Er, how does using globals change the local variables?

--
Steven

Luis M. González

unread,
Feb 23, 2010, 11:44:10 PM2/23/10
to
On Feb 24, 1:15 am, Steven D'Aprano

<ste...@REMOVE.THIS.cybersource.com.au> wrote:
> On Tue, 23 Feb 2010 19:47:22 -0800, Luis M. González wrote:
> > On Feb 23, 10:41 pm, Steven D'Aprano
> > <ste...@REMOVE.THIS.cybersource.com.au> wrote:
> >> On Tue, 23 Feb 2010 15:41:16 -0800, Luis M. González wrote:
> >> > By the way, if you want the variables inside myDict to be free
> >> > variables, you have to add them to the local namespace. The local
> >> > namespace is also a dictionary "locals()". So you can update locals
> >> > as follows:
>
> >> >     locals().update( myDictionary )
>
> >> No you can't. Try it inside a function.
>
> >> --
> >> Steven
>
> > Sure. Inside a function I would use globals() instead. Although I don't
> > know if it would be a good practice...
>
> Er, how does using globals change the local variables?
>
> --
> Steven

Hmmm.... well, you tell me!
As I said, I don't know if this is the recomended way...

Luis

Steven D'Aprano

unread,
Feb 24, 2010, 2:08:19 AM2/24/10
to

I'm not the one that said you can update locals! You said it. I said you
can't, because you *can't*. The docs warn that you can't change locals,
and if you try it, you will see that the docs are right.


>>> def test():
... x = 1
... locals().update(x = 2)
... print x
...
>>>
>>> test()
1

> As I said, I don't know if this is the recomended way...

It's not recommended because it doesn't work.


--
Steven

Luis M. González

unread,
Feb 24, 2010, 5:44:52 AM2/24/10
to
On Feb 24, 4:08 am, Steven D'Aprano

I guess I have to check the docs...
Anyway, nobody wanted to update locals() from within a function here.
Doing it outside of a function seems to work.
And updating globals() works in any case, which is what the OP seems
to need. Isn't it?

Luis

Luis M. González

unread,
Feb 24, 2010, 5:58:38 AM2/24/10
to

Alright, this is what the docs say about locals:
"Note
The built-in functions globals() and locals() return the current
global and local dictionary, respectively, which may be useful to pass
around for use as the second and third argument to exec().

Note
The default locals act as described for function locals() below:
modifications to the default locals dictionary should not be
attempted. Pass an explicit locals dictionary if you need to see
effects of the code on locals after function exec() returns."

I wonder why updating locals(), not from within a function, works (at
least in my interactive session).
And what about the trick of updating globals? Is it legal? If not, is
there any "legal" way to do what the OP needs?

Luis

Bruno Desthuilliers

unread,
Feb 24, 2010, 6:38:10 AM2/24/10
to
Luis M. Gonz�lez a �crit :

> On Feb 23, 5:53 pm, vsoler <vicente.so...@gmail.com> wrote:
>> Hi,
>>
>> I have two dicts
>>
>> n={'a', 'm', 'p'}
>> v={1,3,7}
>>
>> and I'd like to have
>>
>> a=1
>> m=3
>> p=7
>>
>> that is, creating some variables.
>>
>> How can I do this?
>
> You are probably coming from another language and you're not used to
> python's data structures.
> If you want a list of items, you use tuples or lists.

<pedantic>

If you want a list, then you use a list - not a tuple !-)

> Examples:
>
> ('a', 'm', 'p') ---> this is a tuple, and it's made with
> parenthesis ()

It's not the parens that "make" the tuple, it's the commas:

>>> t1 = (1, 2, 3)
>>> t2 = 1, 2, 3
>>> t1
(1, 2, 3)
>>> t2
(1, 2, 3)
>>> type(t2)
<type 'tuple'>
>>>

The only case where the parens are required is to define an empty tuple:
>>> empty = ()
>>> empty
()
>>> type(empty)
<type 'tuple'>

</<pedantic>

Now it's most of the time a good idea to still use the parens since it
makes for more readable code (IMHO...)

(snip helpful content)

Bruno Desthuilliers

unread,
Feb 24, 2010, 6:40:22 AM2/24/10
to
Luis M. Gonz�lez a �crit :
> On Feb 23, 10:41 pm, Steven D'Aprano
> <ste...@REMOVE.THIS.cybersource.com.au> wrote:
>> On Tue, 23 Feb 2010 15:41:16 -0800, Luis M. Gonz�lez wrote:
>>> By the way, if you want the variables inside myDict to be free
>>> variables, you have to add them to the local namespace. The local
>>> namespace is also a dictionary "locals()". So you can update locals as
>>> follows:
>>> locals().update( myDictionary )
>> No you can't. Try it inside a function.
>>
>
> Sure. Inside a function I would use globals() instead.
> Although I don't know if it would be a good practice...

It's even worse than a bad practice. Hint : why is "globals" named
"globals" and not "locals" ?

Bruno Desthuilliers

unread,
Feb 24, 2010, 6:48:13 AM2/24/10
to
Luis M. Gonz�lez a �crit :
(snip)

> Alright, this is what the docs say about locals:
> "Note
> The built-in functions globals() and locals() return the current
> global and local dictionary, respectively, which may be useful to pass
> around for use as the second and third argument to exec().
>
> Note
> The default locals act as described for function locals() below:
> modifications to the default locals dictionary should not be
> attempted. Pass an explicit locals dictionary if you need to see
> effects of the code on locals after function exec() returns."
>
> I wonder why updating locals(), not from within a function, works (at
> least in my interactive session).

Because at the top level, locals and globals are the same thing.

> And what about the trick of updating globals? Is it legal?

It's legal, but it's (usually) a very bad idea - at the top-level, it
harms readability, and from within a function it's doubly bad
(readibility + "globals are evil").

Now as usual with GoldenRules(tm), it's meant to be broken - once you do
know why you shouldn't _usually_ do it.


for the very same reasons global

Luis M. González

unread,
Feb 24, 2010, 8:41:08 AM2/24/10
to
On Feb 24, 8:48 am, Bruno Desthuilliers <bruno.

I still don't understand why is it a bad idea in the case of
globals().
This is the only way I know to define variables programatically in the
top-level namespace, without having to do it manually one by one.
I don't see the readability problem either.
Talking about Goldenrules(tm), what's the recomended way to do it?

Luis

Bruno Desthuilliers

unread,
Feb 24, 2010, 9:44:41 AM2/24/10
to
Luis M. Gonz�lez a �crit :
> On Feb 24, 8:48 am, Bruno Desthuilliers <bruno.
> 42.desthuilli...@websiteburo.invalid> wrote:
>> Luis M. Gonz lez a crit :

>>


>>> And what about the trick of updating globals? Is it legal?
>> It's legal, but it's (usually) a very bad idea - at the top-level, it
>> harms readability, and from within a function it's doubly bad
>> (readibility + "globals are evil").
>>
>> Now as usual with GoldenRules(tm), it's meant to be broken - once you do
>> know why you shouldn't _usually_ do it.
>>

>>> If not, is
>>> there any "legal" way to do what the OP needs?
>

> I still don't understand why is it a bad idea in the case of
> globals().

please not the _usually_.

> This is the only way I know to define variables programatically in the
> top-level namespace, without having to do it manually one by one.

> I don't see the readability problem either.

# wrong.py

x = 42

def bar():
return x + 1


def test():
y = bar()
assert y==43

# snip 1kloc

def foo():
globals()[x] = 43
quux()

# snip some more core

def quux():
globals()[y] = 1138

# snip some more core

if __name__ == '__main__':
foo()


Enjoy...

> Talking about Goldenrules(tm), what's the recomended way to do it?

The "recommanded way" is
1/ to avoid using globals to share state whenever possible
2/ to avoid creating globals from a function

If your problem is to conditionnaly define globals (based on environment
value or whatnot), then just write the conditional at the top level.

Now I don't say there's no legitimate use case for updating the global
namespace from within a function - just that this is a very very very
rare beast (never meet her as far as I'm concerned, and I did write some
hairy code), and even then is BadEnough(tm) to require a good documentation.

FWIW, your example seemed to be about updating the global namespace from
within a function just to have the names available in the function,
which is about the worst possible solution to the OP problem.

wrt/ the OP question, mapping a sequence of values to a sequence of
names is a legitimate concern, but you just dont need to define these
names in the local namespace to use them - just stick'em in a dict and
you're fine.

Rhodri James

unread,
Feb 24, 2010, 6:42:47 PM2/24/10
to
On Wed, 24 Feb 2010 13:41:08 -0000, Luis M. González <lui...@gmail.com>
wrote:

> This is the only way I know to define variables programatically in the
> top-level namespace, without having to do it manually one by one.

We see requests for this a lot, and the response that's frequently missed
amongst all the technical trickery is "What on earth makes you think that
defining variables programatically will help?" Usually the sensible thing
is to collect such "variables" into a list or dictionary, since that's the
only way you're going to access them safely without a whole heap more
technical trickery.

--
Rhodri James *-* Wildebeeste Herder to the Masses

Steven D'Aprano

unread,
Feb 24, 2010, 8:04:54 PM2/24/10
to
On Wed, 24 Feb 2010 02:58:38 -0800, Luis M. González wrote:

> I wonder why updating locals(), not from within a function, works (at
> least in my interactive session).

Because if you're in the global scope, locals() returns globals(), which
is a real namespace and modifying it works.

Inside a function, locals() returns a dict which is a *copy* of the
function namespace. The reason for this is that local namespaces are not
actually dicts, and you can't modify them except by actually assigning
and deleting names in code.


> And what about the trick of updating globals? Is it legal? If not, is
> there any "legal" way to do what the OP needs?

Yes, it is legal to modify globals(). It's just a dict, you can even do
this:

>>> globals()[2] = 4
>>> globals()[2]
4

although that's a pretty useless trick.

But whether you should is another story. I won't say you should NEVER do
so, but it should be rare to use global variables, and even rarer to
create them programmatically. The better solution is almost always to
create your own namespace, namely a dict, and use that explicitly.


--
Steven

Gregory Ewing

unread,
Feb 25, 2010, 2:55:51 AM2/25/10
to
Luis M. González wrote:

> I still don't understand why is it a bad idea in the case of
> globals().
> This is the only way I know to define variables programatically in the
> top-level namespace, without having to do it manually one by one.

The point is that creating variables whose names are computed
at run time is usually a misguided thing to do in the first
place.

Think about it -- how are you going to *use* those variables
that you've created?

If the answer is that you're going to go looking for a way
to read the values of variables whose names are computed at
run time, you might as well not use variables at all, but
just keep their values in a dictionary.

--
Greg

Aahz

unread,
Feb 28, 2010, 2:22:31 AM2/28/10
to
In article <mailman.145.1266968...@python.org>,

Almost true:

>>> x = ()
>>> x
()

Parentheses are definitely needed for the empty tuple.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"Many customs in this life persist because they ease friction and promote
productivity as a result of universal agreement, and whether they are
precisely the optimal choices is much less important." --Henry Spencer

0 new messages