Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use variable as key name in python dictionary

This feels redundant:

name = 'Isaiah'
myInfo = {
  'name': name
}

Is there a shorter, idiomatic way to do this, like in JavaScript:

myInfo = { name }

Edit: changed the variable name from dict to myInfo, since dict is a keyword.

like image 924
Isaiah Taylor Avatar asked May 20 '18 20:05

Isaiah Taylor


People also ask

Can a Python dictionary key be a variable?

When we assign the keys with variables, only the values are used during the dictionary creation. The key must be hashable. This means it is immutable : static and cannot be modified .

Can you use a set as a key in a dictionary Python?

Yes. According to the docs, Frozenset is hashable because it's immutable. This would imply that it can be used as the key to a dict, because the prerequisite for a key is that it is hashable.


2 Answers

In the very rare case where you're trying to make a dict out of a huge and/or dynamic subset of the local, global, or self namespace, you can do that by filtering the appropriate namespace:

keys = set('name age height balance hoopiness'.split())
d = {key: value for (key, value) in locals().items()
     if key in keys}

But obviously this is not worth doing for a simple case. The shortest you could make it would be:

d = {key: value for (key, value) in locals().items() if key == 'name'}

… which does avoid repeating name, but is very, very silly.

For just creating a dict out of one or two statically-named variables, you should just be explicit:

d = {'name': name}
d = dict(name=name)
like image 115
abarnert Avatar answered Sep 18 '22 01:09

abarnert


I came onto SO today because I had the same question. I must say, I am quite disheartened by the answers! I agree with you that this redundancy should have an idiomatic solution. And this is a rare case where Javascript seems to be more sensible than Python. So I would like to add two suggestions.

First, just to say that Abarnert is correct that you should be explicit if it is only one or two variables. I would say even if it is more than that, explicit construction is usually going to be better. But I do think that there are instances where shortcuts are permissible. For example, I have a file that builds up dictionaries to send data via Python Requests. That's all it does. And in every case, I end up make a dictionary where the keys are the same as variables I had defined. I think that that would be an example of a file where using shortcuts is acceptable.

First, you can make use of the eval builtin. This command is usually avoided, but this is a case where it can help, because it can take in a string which is the name of a variable, and spit out the variable value:

def main():
    #variables
    foo = "hello world"
    bar = 10
    baz = [1, 2, 3]

    # Build the dictionary:
    args = ("foo", "bar", "baz")
    dictionary = dict()
    for arg in args:
        dictionary[arg] = eval(arg)
    print(dictionary)


if __name__ == "__main__":
    main()

Try it out. Note that it would be difficult to wrap this functionality into some sort of class or function, because of variable scope. Even using dictionary comprehension will fail. But if you're happy adding in 3 lines flat in a function like that, it will work.

Second, consider whether you can assign the values to the variables as you build the dictionary. So instead of:

foo = 4+5
dictionary = dict(foo=foo)

Try:

dictionary = dict(
    foo=4+5
)

If you need to use the earlier values in later calculations, initialise the dictionary first, and then combine calculation with dict assignment as well:

dictionary = dict()
dictionary['foo'] = 4 + 5
dictionary['bar'] = dictionary['foo'] + 9

Something that I think might also help with the above case is the new PEP that allows you to assign aliases in a calculation. The one that the BDFL resigned over. So let's hope that gets implemented soon!

Finally, just a quick comment on the accepted answer, the fact that Python has already used {} to mean set, doesn't mean we can't create this functionality (why not <> or D() or something?). Just my 2 cents. I think this is a needed feature.

like image 26
Neil Avatar answered Sep 18 '22 01:09

Neil