将字典条目转换为变量 [duplicate]

Convert dictionary entries into variables [duplicate]

提问人:HappyPy 提问时间:8/7/2013 最后编辑:ggorlenHappyPy 更新时间:11/29/2021 访问量:124440

问:

这个问题在这里已经有答案了:
去年关闭。

社区在 10 天前审查了是否重新讨论这个问题,并将其关闭:

原始关闭原因未解决

有没有一种 Python 方法可以将字典的值分配给其键,以便将字典条目转换为变量? 我试过了这个:

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

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

python 字典

评论

14赞 8/7/2013
将数据排除在变量名称之外
4赞 Ashwini Chaudhary 8/7/2013
动态创建变量不是一个好主意。
1赞 HappyPy 8/7/2013
@Zero 比雷埃夫斯 - 我的问题与我创建的条目有关,而不是由其他用户创建的条目,因此它与您提到的帖子中发布的问题略有不同
1赞 Charlie Parker 10/17/2017
@AshwiniChaudhary为什么不呢?
0赞 ggorlen 11/29/2021
参见 在 Python 中将有限的字典值解压缩为局部变量的优雅方法

答:

34赞 user2357112 8/7/2013 #1

你已经有一本非常好的词典了。就用它吧。如果你知道钥匙是什么,并且你绝对确定这是一个合理的想法,你可以做这样的事情

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

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

评论

1赞 HappyPy 8/7/2013
谢谢你的回答。是的,我确定键会是什么,因为我创建了它们,并且只想在其他地方使用完全相同的变量名称。我只是想知道是否有更自动的方法可以做到这一点,因为我可能有 20 多个条目。
7赞 user2357112 8/7/2013
@user2635863:你可能正在寻找一个班级。如果您有 20 个变量都需要保存,那么您就有问题了。
0赞 Iuri Guilherme 12/4/2022
@HappyPy你不需要 20+ 个命名变量,但逻辑应该允许你直接在另一个函数中解压缩字典(例如,你的 20+ 个变量可以是一个函数的命名参数)
13赞 tdelaney 8/7/2013 #2

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

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

d = {'a':1, 'b':2}
vars = Bunch(d)
print vars.a, vars.b

评论

8赞 PM 2Ring 8/23/2019
你为什么要跟踪 vars
0赞 Gringo Suave 1/19/2022
SimpleNamespace 已经包含了很长一段时间,尽管名称很麻烦,但我同意。
60赞 HappyPy 9/6/2013 #3

这就是我一直在寻找的:

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

评论

5赞 belteshazzar 4/17/2016
list(map(exec, ("{0}={1}".format(x[0],x[1]) for x in d.items())))
2赞 nat chouf 2/2/2018
@dblissfor k,v in d.items(): exec(k+'=v')
0赞 ajsp 7/22/2018
甜蜜的答案,使我不必声明一大堆mongodb变量。@dblis你可以做到 这是我书中的一行。for key,val in dp.items(): exec(key + '=val')
8赞 bugmenot123 6/26/2019
小心 eval,你的 dict 可能有或更糟。import shutil;shutil.rmtree('/')
3赞 Gringo Suave 12/24/2020
应该投反对票。无需使用 exec,请参阅其他地方的本地人答案。
0赞 restrepo 2/12/2015 #4

使用熊猫:

import pandas as pd
var=pd.Series({'a':1, 'b':2})
#update both keys and variables
var.a=3
print(var.a,var['a'])

评论

10赞 Manuel G 3/15/2015
我喜欢熊猫,但这可能有点矫枉过正(需要熊猫只是为了让你获得变量作为辅助工具)。
1赞 RajeshM 11/25/2018
正是我需要的。我有一个字典,其中的值是 pandas 数据帧。所以使用这个解决方案是完全有意义的。谢谢!
181赞 Peque 3/17/2016 #5

您可以使用以下命令在一行中完成:

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

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

注意

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

相反,我宁愿始终使用命名空间。

使用 Python 3,您可以:

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

如果您坚持使用 Python 2 或需要使用类型中缺少的某些功能。SimpleNamespace,您还可以:

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

如果您不希望修改您的数据,您不妨考虑使用 collections.namedtuple,它在 Python 3 中也可用。

评论

10赞 Yuval A. 7/16/2017
请注意,在函数中不起作用。(将与 globals() “合作”,但它将分配全局变量,而不是函数的局部变量......
0赞 Charlie Parker 10/17/2017
我收到错误,为什么?AttributeError: 'builtin_function_or_method' object has no attribute 'update'
2赞 Peque 10/17/2017
@CharlieParker 也许你忘记了括号?😉
4赞 shahar_m 3/20/2018
您还可以使用 .这将在函数中起作用。globals().update(d)
22赞 suhailvs 11/10/2019 #6

可以使用 operator.itemgetter

>>> from operator import itemgetter
>>> d = {'a':1, 'b':2}
>>> a, b = itemgetter('a', 'b')(d)
>>> a
1
>>> b
2

评论

0赞 Hans Bouwmeester 2/26/2022
这是 Python 解构字典的方法。虽然不像 Javascript 那样简写,但对于读者来说,它很容易理解正在发生的事情,并且不会混合数据和变量名称。
2赞 ggorlen 6/11/2022
不错,但不幸的是没有那么吸引人。使用单字母变量名称,一切看起来都不错。此外,每个脚本都可以导入您可能只想执行一次或两次操作。foobar, foobaz = itemgetter("foobar", "foobaz")(dictionary)
1赞 Iuri Guilherme 12/4/2022
这比像 OP 问题那样解压缩 20+ 命名变量更容易吗?你可以这样做,但无论如何你都必须在左侧输入每个命名的变量itemgetter(*d.keys())(d)
6赞 ggorlen 11/29/2021 #7

Python 对列表解包有很好的支持,但不支持 dict 或对象解包。最不出人意料的 Python 方法似乎是手动访问每个项目以构建一个中间元组,如以下答案所述:

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"]