【问题标题】:Create dictionary where keys are variable names创建字典,其中键是变量名
【发布时间】:2020-05-28 23:33:43
【问题描述】:

我经常想创建一个字典,其中键是变量名。例如,如果我有变量 ab 我想生成:{"a":a, "b":b}(通常在函数末尾返回数据)。

python 中是否有任何(理想情况下是内置的)方法可以自动执行此操作?即有一个函数使得create_dictionary(a,b) 返回{"a":a, "b":b}

【问题讨论】:

  • "a":a 没有多大意义,a 将被其价值所取代。
  • 虽然肯定有办法做到这一点(使用locals()),但我认为这很少是一个好的解决方案。在您给出的示例中(从函数返回多个值),请考虑从集合模块返回 namedtuple
  • @AnttiHaapala 一个可以经常使用它的地方是在传递给 html 模板的 Django 上下文数据中。 {"a":a, "b":b} 是有意义的,其中视图中的变量名称与模板中的相同。
  • 这能回答你的问题吗? create dictionary from list of variables

标签: python python-3.x


【解决方案1】:

您是否考虑过创建一个班级?可以将类视为字典的包装器。

# Generate some variables in the workspace
a = 9; b = ["hello", "world"]; c = (True, False)

# Define a new class and instantiate
class NewClass(object): pass
mydict = NewClass()

# Set attributes of the new class
mydict.a = a
mydict.b = b
mydict.c = c

# Print the dict form of the class
mydict.__dict__
{'a': 9, 'b': ['hello', 'world'], 'c': (True, False)}

如果您想传递变量名列表,也可以使用setattr 函数:

mydict = NewClass()
vars = ['a', 'b', 'c']
for v in vars: 
    setattr(mydict, v, eval(v)) 

mydict.__dict__
{'a': 9, 'b': ['hello', 'world'], 'c': (True, False)}

【讨论】:

    【解决方案2】:

    您可以为create_dict编写自己的函数

    def create_dict(*args):
      return dict({i:eval(i) for i in args})
    
    a = "yo"
    b = 7
    print (create_dict("a", "b"))
    

    这给出了{'a': 'yo', 'b': 7} 的输出。
    这是一个简单的生成器:

    vars = ["a", "b"]
    create_dict = {i:eval(i) for i in args}
    

    或者你可以使用这个单行 lambda 函数

    create_dict = lambda *args: {i:eval(i) for i in args}
    print (create_dict("a", "b"))
    

    但是,如果您想将变量而不是变量名作为字符串传递给函数,那么实际上将变量名作为字符串获取是相当麻烦的。但如果是这种情况,那么您可能应该尝试使用Nf4r 使用的locals()vars()globals()

    【讨论】:

    • "Is using eval in Python a bad practice?",通常eval 不应该是首选工具。
    • 在这种情况下完全没有问题。
    • 请注意,literal eval 甚至不起作用,因为名称不是文字。
    • 你是对的,它没有,也许应该坚持eval 我猜。
    • 我认为在上述情况下使用eval至少没有任何问题。
    【解决方案3】:

    扩展@Nf4r 的代码,我使用类似:

    a, b = 1, 2
    
    def make_dict(*args):
        # Globals will change of size, so we need a copy
        g = {k: v for k, v in globals().items() if not k.startswith('__')}  
    
        result = {}
        for arg in args:
            for k, v in g.items():
                try:
                    if v == arg:
                        result[k] = v
                except ValueError:
                    continue  # objects that don't allow comparison
    
        return result
    
    make_dict(a, b)
    

    【讨论】:

    • 感谢您在此处编写此解决方案。尽管它搜索全局变量,但它似乎效率低下。您可能遇到过更好的解决方案吗?
    【解决方案4】:

    您是否尝试过类似的方法:

    a, b, c, d = 1, 2, 3, 4
    dt = {k:v for k, v in locals().items() if not k.startswith('__')}
    print(dt)
    {'a': 1, 'd': 4, 'b': 2, 'c': 3}
    

    【讨论】:

    • 但是如果我之前已经定义了很多变量,那么它会显示太多
    猜你喜欢
    • 1970-01-01
    • 2014-10-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 2019-02-23
    • 1970-01-01
    相关资源
    最近更新 更多