【问题标题】:Convert dictionary entries into variables将字典条目转换为变量
【发布时间】:2013-08-08 01:53:55
【问题描述】:

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

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

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

【问题讨论】:

标签: python dictionary


【解决方案1】:

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

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

但大多数时候,您应该只使用字典。 (如果使用字典不方便,可能是您没有很好地组织数据;请寻求帮助重新组织它。)

【讨论】:

  • 感谢您的回答。是的,我确定键是什么,因为我创建了它们,并且只想在其他地方使用完全相同的变量名。我只是想知道是否有更自动的方法可以做到这一点,因为我可能有超过 20 个条目。
  • @user2635863:您可能正在寻找class。如果您有 20 个变量都需要保存,那么您就有问题了。
【解决方案2】:

考虑Python: load variables in a dict into namespace 中的“Bunch”解决方案。您的变量最终成为新对象的一部分,而不是局部变量,但您可以将它们视为变量而不是 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

【讨论】:

  • 你为什么要关注vars
【解决方案3】:

这就是我要找的东西:

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

【讨论】:

  • list(map(exec, ("{0}={1}".format(x[0],x[1]) for x in d.items())))
  • @dbliss for k,v in d.items(): exec(k+'=v')
  • 甜蜜的答案,让我不必声明一大堆 mongodb 变量。 @dblis 你可以这样做 for key,val in dp.items(): exec(key + '=val') 这是我书中的一行。
  • 小心 eval,你的 dict 可能有 import shutil;shutil.rmtree('/') 或更糟。
  • 应该被否决。无需使用 exec,在其他地方查看当地人的答案。
【解决方案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'])

【讨论】:

  • 我喜欢 pandas,但这可能有点矫枉过正(需要 pandas 才能将变量作为访问器)。
  • 正是我需要的。我有一个字典,其中的值是熊猫数据框。所以使用这个解决方案是完全有意义的。谢谢!
【解决方案5】:

您可以在一行中完成:

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

但是,您应该小心how Python may optimize locals/globals access when using this trick

注意

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

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

使用 Python 3,您可以:

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

如果你被 Python 2 卡住或者需要使用some features missing in types.SimpleNamespace,你也可以:

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

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

【讨论】:

  • 注意,在函数内部不起作用。 (将与 globals() 一起“工作”,但它会分配全局变量,而不是函数的局部变量......)
  • 我收到了错误AttributeError: 'builtin_function_or_method' object has no attribute 'update',为什么?
  • @CharlieParker 也许你忘记了括号? ?
  • 您也可以使用globals().update(d)。这将在函数内部工作。
【解决方案6】:

你可以使用operator.itemgetter

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

【讨论】:

    【解决方案7】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 2017-05-15
      • 2019-12-03
      • 2011-09-19
      • 2016-11-20
      • 2021-07-14
      相关资源
      最近更新 更多