将字典条目转换为变量 - python

Hap*_*yPy 32 python dictionary

是否有一种pythonic方法将字典值分配给其键,以便将字典条目转换为变量?我试过这个:

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

        exec(key)=val
                 ^ 
        SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

更新:也许我应该更具体:我确实知道键值对是正确的,因为它们之前被我定义为变量.然后我将这些变量存储在字典中(作为键值对),并希望在不同的函数中重用它们.我可以在新函数中重新定义它们,但因为我可能有一个包含大约20个条目的字典,我认为可能有一种更有效的方法.

Peq*_*que 67

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

>>> d = {'a': 1, 'b': 2}
>>> locals().update(d)
>>> a
1
Run Code Online (Sandbox Code Playgroud)

我看到这个解决方案的另一个线程.虽然你应该小心Python在使用这个技巧时如何优化本地/全局访问.

注意

我认为这样的编辑locals()通常是一个坏主意.如果你认为globals()是一个更好的选择,那就考虑两下吧!:-D

我宁愿总是使用命名空间:

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

  • 注意,在函数内部不起作用.(将使用globals()"工作",但它将分配全局变量,而不是函数的本地变量...) (7认同)
  • 您还可以使用`globals().update(d)`。这可以在函数内部工作。 (4认同)
  • @CharlieParker也许你忘记了括号? (2认同)
  • [文档明确警告不要更新 `locals()` 的返回值](https://docs.python.org/3/library/functions.html#locals)。 (2认同)

Hap*_*yPy 29

这就是我想要的:

>>> d = {'a':1, 'b':2}
>>> for key,val in d.items():
        exec(key + '=val')
Run Code Online (Sandbox Code Playgroud)

  • `list(map(exec,("{0} = {1}".格式(x [0],x [1]),用于d.items()中的x))) (4认同)
  • 小心 eval,你的 dict 可能有 `import shutil;shutil.rmtree('/')` 或更糟。 (4认同)
  • 应该被否决。无需使用 exec,请参阅其他地方的当地人答案。 (3认同)
  • @dbliss`对于d.items()中的k,v:exec(k +'= v')` (2认同)

use*_*ica 19

你已经有了一本非常好的字典.只是使用它.如果你知道键是什么,并且你绝对相信这是一个合理的想法,你可以做类似的事情

a, b = d['a'], d['b']
Run Code Online (Sandbox Code Playgroud)

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

  • @ user2635863:您可能正在寻找[类](http://docs.python.org/2/tutorial/classes.html).如果你有20个变量都需要保存,那你就有问题了. (6认同)

suh*_*lvs 10

你可以使用operator.itemgetter

>>> from operator import itemgetter
>>> d = {'a':1, 'b':2}
>>> a, b = itemgetter('a', 'b')(d)
>>> a
1
>>> b
2
Run Code Online (Sandbox Code Playgroud)

  • 不错,但不幸的是 `foobar, foobaz = itemgetter("foobar", "foobaz")(dictionary)` 并不那么有吸引力。单字母变量名的一切看起来都很好。另外,每个脚本都有一个导入,用于您可能只想执行一次或两次的操作。 (2认同)

tde*_*ney 9

考虑Python中的"束"解决方案:将dict中的变量加载到命名空间中.您的变量最终成为新对象的一部分,而不是本地,但您可以将它们视为变量而不是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
Run Code Online (Sandbox Code Playgroud)

  • 你为什么要跟踪[vars](https://docs.python.org/3/library/functions.html#vars)? (4认同)

ggo*_*len 6

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

a, b = d['a'], d['b']
Run Code Online (Sandbox Code Playgroud)

但是,如果您有很多属性,或者变量名称很长,那么执行起来可能会很麻烦:

great, wow, awesome = dictionary['great'], dictionary['wow'], dictionary['awesome']
Run Code Online (Sandbox Code Playgroud)

对于上下文,上面(解构)的 JavaScript 等效项是:

const {great, wow, awesome} = dictionary;
Run Code Online (Sandbox Code Playgroud)

这是一个更加动态的选项:

>>> dictionary = dict(great=0, wow=1, awesome=2)
>>> great, wow, awesome = (dictionary[k] for k in ("great", "wow", "awesome"))
>>> great
0
>>> awesome
2
Run Code Online (Sandbox Code Playgroud)

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

>>> 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")
Run Code Online (Sandbox Code Playgroud)

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

>>> 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
Run Code Online (Sandbox Code Playgroud)

毕竟,对于需要安全且易于理解的实际生产代码来说,在多行上手动解包可能是最好的:

>>> 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
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

38524 次

最近记录:

6 年 前