Idok
Idok

Reputation: 4132

Create dictionary from list of variables

I'm looking for a way to create a dictionary without writing the key explicitly. I want to create a function that gets the number of variables and creates a dictionary where the variable names are the keys and their values are the variable values.

Instead of writing the following function:

def foo():
    first_name = "daniel"
    second_name = "daniel"
    id = 1
    return {'first_name':first_name, 'second_name':second_name}

I want to get the same result with function :

create_dict_from_variables(first_name, second_name)

Is there any way to do so?

Upvotes: 60

Views: 51771

Answers (8)

C-3PO
C-3PO

Reputation: 1213

There is an interesting solution to this problem, which doesn't involve external libraries. However, a slightly different syntax is needed: eval(f(a,b))

# Auxiliary Function
f = lambda s: f"dict({ ','.join( f'{k}={k}' for k in s.split(',') ) })"

first_name  = "daniel"
second_name = "joe"
D           = eval(f('first_name,second_name'))

print(D)
# {'first_name': 'daniel', 'second_name': 'joe'}

In the example above, the main goal of the OP is still accomplished, in the sense that we only type the names of the variables once to create a dictionary. However, the syntax is still a bit verbose.

PS. One important benefit of the code above is that we evaluate the dictionary in its original namespace, which removes any restrictions with respect to the scope of the function (globals(), locals(), etc.). This was my main motivation behind using this approach.

Upvotes: 1

Alexey Demin
Alexey Demin

Reputation: 2768

pip install sorcery

from sorcery import dict_of

a = 1
b = 2
c = 3
d = dict_of(a, b, c)
print(d)
# {'a': 1, 'b': 2, 'c': 3}

Upvotes: 27

Synthaze
Synthaze

Reputation: 6090

In fact, there is a way:

from varname import nameof

def foo(first_name,second_name):
    return {nameof(first_name):first_name, nameof(second_name):second_name}

first_name = "daniel"
second_name = "daniel"

print (foo(first_name,second_name))

Output:

{'first_name': 'daniel', 'second_name': 'daniel'}

You can get the python-varname package below:

https://github.com/pwwang/python-varname

Basic use:

from varname import nameof

s = 'Hey!'

print (nameof(s))

Output:

s

Upvotes: 1

Vasus
Vasus

Reputation: 31

In principle this is possible by passing variable names to function create_dict and then reaching to a caller stack frame from within create_dict function using module inspect.

Upvotes: 3

Not_a_Golfer
Not_a_Golfer

Reputation: 49187

You can't do it without writing at least the variable names, but a shorthand can be written like this:

>>> foo = 1
>>> bar = 2
>>> d = dict(((k, eval(k)) for k in ('foo', 'bar')))
>>> d
{'foo': 1, 'bar': 2}

or as a function:

def createDict(*args):
     return dict(((k, eval(k)) for k in args))

>>> createDict('foo','bar')
{'foo': 1, 'bar': 2}

you can also use globals() instead of eval():

>>> dict(((k, globals()[k]) for k in ('foo', 'bar')))

Upvotes: 32

Greg Hewgill
Greg Hewgill

Reputation: 993025

No, there isn't, because Python functions don't get information about the variables used to call the function. Also, imagine doing something like this:

create_dict_from_variables(first_name[:-3] + "moo", last_name[::2])

The function will have no way of knowing the expressions used to create the parameters.

Upvotes: 2

Chris Morgan
Chris Morgan

Reputation: 90742

You can use locals, but I would recommend against it. Do it explicitly.

>>> import this
[...]
Explicit is better than implicit.
[...]

Your code will generally be better, more predictable, less prone to breaking and more comprehensible if you do it explicitly.

Upvotes: 8

eumiro
eumiro

Reputation: 212845

You cannot do this.

Your function could be defined as:

def create_dict_from_variables(first_name, second_name):
    return something_from(first_name, second_name)

and you can call this function:

create_dict_from_variables('abcd', 'efgh')

These two arguments 'abcd' and 'efgh' are not named variables.

Upvotes: -4

Related Questions