82

是否有一种 Pythonic 方法可以将字典的值分配给它的键,以便将字典条目转换为变量?我试过了:

>>> d = {'a':1, 'b':2}
>>> for key,val in d.items():
        exec('exec(key)=val')
            
        exec(key)=val
                 ^ 
        SyntaxError: invalid syntax

我确信键值对是正确的,因为它们之前被我定义为变量。然后我将这些变量存储在字典中(作为键值对),并希望在不同的函数中重用它们。我可以在新函数中重新定义它们,但是因为我可能有一个包含大约 20 个条目的字典,所以我认为可能有一种更有效的方法来执行此操作。

4

7 回答 7

142

您可以在一行中执行此操作:

>>> d = {'a': 1, 'b': 2}
>>> locals().update(d)
>>> a
1

但是,在使用此技巧时,您应该注意Python 如何优化本地/全局访问

笔记

我认为这样locals()的编辑通常是一个坏主意。如果您认为globals()是更好的选择,请三思而后行!:-D

相反,我宁愿总是使用命名空间。

使用 Python 3,您可以:

>>> from types import SimpleNamespace    
>>> d = {'a': 1, 'b': 2}
>>> n = SimpleNamespace(**d)
>>> n.a
1

如果你被 Python 2 卡住了,或者如果你需要使用中缺少的一些特性types.SimpleNamespace,你还可以:

>>> from argparse import Namespace    
>>> d = {'a': 1, 'b': 2}
>>> n = Namespace(**d)
>>> n.a
1

如果您不希望修改数据,不妨考虑使用collections.namedtuplePython 3 中也提供的 .

于 2016-03-17T11:24:49.713 回答
54

这就是我一直在寻找的:

>>> d = {'a':1, 'b':2}
>>> for key,val in d.items():
        exec(key + '=val')
于 2013-09-05T23:46:30.867 回答
31

你已经有了一本非常好的词典。就用那个。如果您知道密钥将是什么,并且您绝对确定这是一个合理的想法,您可以执行类似的操作

a, b = d['a'], d['b']

但大多数时候,你应该只使用字典。(如果使用字典很尴尬,你可能没有很好地组织你的数据;请求帮助重新组织它。)

于 2013-08-06T21:30:42.767 回答
13

你可以使用operator.itemgetter

>>> from operator import itemgetter
>>> d = {'a':1, 'b':2}
>>> a, b = itemgetter('a', 'b')(d)
>>> a
1
>>> b
2
于 2019-11-10T00:35:42.957 回答
10

考虑 Python 中的“Bunch”解决方案:将 dict 中的变量加载到 namespace中。您的变量最终成为新对象的一部分,而不是局部变量,但您可以将它们视为变量而不是 dict 条目。

class Bunch(object):
    def __init__(self, adict):
        self.__dict__.update(adict)

d = {'a':1, 'b':2}
vars = Bunch(d)
print vars.a, vars.b
于 2013-08-06T22:41:57.513 回答
3

Python 非常支持列表解包,但不支持 dict 或对象解包。最令人惊讶和 Pythonic 的方法似乎是手动访问每个项目以构建一个中间元组,如本答案中所述:

a, b = d['a'], d['b']

但是,如果你有很多属性,或者变量名很长,这样做会很麻烦:

great, wow, awesome = dictionary['great'], dictionary['wow'], dictionary['awesome']

对于上下文,上述(解构)的 JavaScript 等价物是:

const {great, wow, awesome} = dictionary;

这是一个更动态的选项:

>>> dictionary = dict(great=0, wow=1, awesome=2)
>>> great, wow, awesome = (dictionary[k] for k in ("great", "wow", "awesome"))
>>> great
0
>>> awesome
2

这仍然很冗长;你可以写一个函数来抽象一些东西,但不幸的是你仍然需要输入两次:

>>> def unpack(dct, *keys):
...     return (dct[k] for k in keys)
... 
>>> dictionary = dict(great=0, wow=1, awesome=2)
>>> great, wow, awesome = unpack(dictionary, "great", "wow", "awesome")

您也可以将其推广到对象上:

>>> def unpack(x, *keys):
...     if isinstance(x, dict):
...         return (x[k] for k in keys)
...     return (getattr(x, k) for k in keys)
...
>>> from collections import namedtuple
>>> Foo = namedtuple("Foo", "a b c d e")
>>> foo = Foo(a=0, b=1, c=2, d=3, e=4)
>>> c, b, d, a = unpack(foo, "c", "b", "d", "a")
>>> d
3

毕竟,在多行上手动解包可能最适合您需要安全且易于理解的实际生产代码:

>>> great = dictionary["great"]
>>> wow = dictionary["wow"]
>>> awesome = dictionary["awesome"]
于 2021-11-28T16:25:44.913 回答
1

使用熊猫:

import pandas as pd
var=pd.Series({'a':1, 'b':2})
#update both keys and variables
var.a=3
print(var.a,var['a'])
于 2015-02-11T21:03:07.427 回答