Reputation: 87077
Say you have,
foo = 'bar'
d = {'a-key':'a-value'}
And you want
d = {'a-key':'a-value','foo':'bar'}
e = {'foo':foo}
I know you can do,
d['foo'] = foo
#Either of the following for e
e = {'foo':foo}
e = dict(foo=foo)
But, in all these way to add the variable foo to dict, I have had to use the word foo
twice; once to indicate the key and once for its value.
It seems wasteful to me to use foo
twice. Is there a simpler way, in which you can tell python "Add this variable to the dictionary with its name as the key and its value as the value"?
Upvotes: 1
Views: 18288
Reputation: 556
It seems to me what you are talking about is an enhancement to parameter passing functionality:
def func(*vars):
provides a tuple of ordered values without keys
def func(**vars):
provides a dict of key value pairs, that MUST be passed as key=value pairs.
def func(***vars):
WOULD PROVIDE a dict of key value pairs, passed either explicitly as key=value, or implicitly as key (a variable, literals would cause error without key=)
SO:
(x1,x2,x3) = (1,2,3)
def myfunc(***vars):
retrun vars
myfunc(x1,x2,x3)
>>> {'x1':1,'x2':2,'x3':3}
But of course, this is just wishful thinking...
Upvotes: 0
Reputation: 21548
To add all the local variables to a dict you can do:
d.update(locals())
The same works for function calls:
func(**locals())
Note that depending on where you are locals()
might of course contain stuff that should not end up in the dict. So you could implement a filter function:
def filtered_update(d, namespace):
for key, value in namespace.items():
if not key.startswith('__'):
d[key] = value
filtered_update(d, locals())
Of course the Python philosophy is "explicit is better than implicit", so generally I would walk the extra mile and do this kind of stuff by hand (otherwise you have to be careful about what goes on in your local namespace).
Upvotes: 1
Reputation: 11242
If you don't want to pass all of locals()
(which may be a security risk if you don't fully trust the function you're sending the data too), a one-line answer could be this:
dict([ (var, locals()[var]) for var in ['foo', 'bar'] ])
or in Python 3.0 this would become possible:
{ var: locals()[var] for var in ['foo', 'bar'] }
Upvotes: 1
Reputation: 10409
You could use eval, although I'm not sure that I'd recommend it.
>>> d = dict()
>>> foo = 'wibble'
>>> def add(d, name):
d[name] = eval(name)
>>> add(d, 'foo')
>>> d
{'foo': 'wibble'}
Edit: I should point out why I don't recommend "eval". What happens if you do something like this? (from: http://mail.python.org/pipermail/tutor/2005-November/042854.html)
>>> s = "(lambda loop: loop(loop)) (lambda self: self(self))"
>>> add(d, s)
Traceback (most recent call last):
File "<pyshell#54>", line 1, in <module>
add(d, s)
File "<pyshell#43>", line 2, in add
d[name] = eval(name)
File "<string>", line 1, in <module>
File "<string>", line 1, in <lambda>
File "<string>", line 1, in <lambda>
...
File "<string>", line 1, in <lambda>
RuntimeError: maximum recursion depth exceeded
Upvotes: 0
Reputation: 54081
Actutally using foo
twice is remarkably common in python programs. It is used extensively for passing on arguments eg
def f(foo, bar):
g(foo=foo)
Which is a specialised case of the dictionary manipulations in your question.
I don't think there is a way of avoiding it without resorting to magic, so I think you'll have to live with it.
Upvotes: 2
Reputation: 88717
you can do something like this
def add_dry_foo(d, namespace, fooName):
d[fooName] = namespace[fooName]
foo = 'oh-foo'
d = {}
add_dry_foo(d, locals(), 'foo')
print d
Upvotes: 4
Reputation: 375474
You can use:
name = 'foo'
d[name] = vars[name]
I don't see the difference between your d
and e
cases: both set 'foo' to the value of foo.
It gets trickier if you want to bury this in a function:
def add_variable(d, name):
# blah
because then it has to use inspect
to start poking around in frames.
This sounds like a larger problem that might have a nicer solution if you wanted to describe it to us. For example, if the problem is that you don't care just about foo, but in fact, a whole slew of local variables, then maybe you want something like:
d.update(locals())
which will copy the names and value of all the local variables into d
.
Upvotes: 2