Given a list of variable names in Python, how do I a create a dictionary with the variable names as keys (to the variables' values)?

后端 未结 4 1636
逝去的感伤
逝去的感伤 2020-12-17 16:04

I have a list of variable names, like this:

[\'foo\', \'bar\', \'baz\']

(I originally asked how I convert a list of variables. See Greg He

相关标签:
4条回答
  • 2020-12-17 16:30

    Not efficient, but without invoking eval:

    dict((k,v) for (k,v) in globals().iteritems() if k in list_of_variable_names)
    

    or

    dict((k,v) for (k,v) in vars().iteritems() if k in list_of_variable_names)
    

    depending on what you want.

    0 讨论(0)
  • 2020-12-17 16:45

    You can use list or generator comprehensions to build a list of key, value tuples used to directly instantiate a dict. The best way is below:

    dict((name, eval(name)) for name in list_of_variable_names)
    

    In addition, if you know, for example, that the variables exist in the local symbol table you can save yourself from the dangerous eval by looking the variable directly from locals:

    dict((name, locals()[name]) for name in list_of_variable_names)
    

    After your final update, I think the answer below is really what you want. If you're just using this for string expansion with strings that you control, just pass locals() directly to the string expansion and it will cherry-pick out the desired values

    If, however, these strings could ever come from an outside source (e.g. translation files), than it's a good idea to filter locals()

    0 讨论(0)
  • 2020-12-17 16:48

    Your original list [foo, bar, baz] doesn't contain the variable names, it just contains elements that refer to the same values as the variables you listed. This is because you can have two different variable names that refer to the same value.

    So, the list by itself doesn't contain information about what other names refer to the objects. The first element in your array has the name foo but it also has the name a[0] (assuming your array is called a). After executing the following code, quux also refers to the same object:

    quux = a[0]
    

    Update: You're right that you can use eval() for that, but its use is generally discouraged. Python provides a special member named __dict__ that contains the symbol table for the current module. So you can:

    import __main__
    d = dict((x, __main__.__dict__[x]) for x in list_of_variable_names)
    

    Having to import __main__ when your code is in the unnamed main module is a quirk of Python.

    0 讨论(0)
  • 2020-12-17 16:49

    Forget filtering locals()! The dictionary you give to the formatting string is allowed to contain unused keys:

    >>> name = 'foo'
    >>> zip = 123
    >>> unused = 'whoops!'
    >>> locals()
    {'name': 'foo', 'zip': 123, ... 'unused': 'whoops!', ...}
    >>> '%(name)s %(zip)i' % locals()
    'foo 123'
    

    With the new f-string feature in Python 3.6, using locals() is no longer necessary:

    >>> name = 'foo'
    >>> zip = 123
    >>> unused = 'whoops!'
    >>> f'{zip: >5} {name.upper()}'
    '  123 FOO'
    
    0 讨论(0)
提交回复
热议问题