将有限的字典值解压到Python中的局部变量中的优雅方法

问题描述 投票:0回答:6

我正在寻找一种优雅的方法来将 Python 字典中的一些值提取到本地值中。

与此等效的东西,但对于更长的值列表和更长的键/变量名称来说更清晰:

d = { 'foo': 1, 'bar': 2, 'extra': 3 }
foo, bar = d['foo'], d['bar']

我最初希望得到类似以下的东西:

foo, bar = d.get_tuple('foo', 'bar')

我可以轻松编写一个不错的函数:

def get_selected_values(d, *args):
    return [d[arg] for arg in args]

foo, bar = get_selected_values(d, 'foo', 'bar')

但我一直怀疑还有其他内置方法。

python
6个回答
56
投票

你可以做类似的事情

foo, bar = map(d.get, ('foo', 'bar'))

foo, bar = itemgetter('foo', 'bar')(d)

这可能会节省一些打字时间,但本质上与您正在做的事情相同(这是一件好事)。


4
投票

有点可怕,但是:

globals().update((k, v) for k, v in d.iteritems() if k in ['foo', 'bar'])

请注意,虽然这是可能的 - 这是您真正不想做的事情,因为您会污染应该留在

dict
本身内部的名称空间...


2
投票

好吧,如果你提前知道名字,你就可以按照你的建议去做。

如果您事先不知道它们,请坚持使用字典 - 这就是它们的用途。

如果您坚持,替代方案是:

varobj = object()
for k,v in d.iteritems(): setattr(varobj,k,v)

之后,键将成为

varobj
上的变量。


0
投票

locals()
写入当地人在过去并不总是有效。 (下面代码的全局版本应该可以在早期版本中使用。)

TL;博士:

locals().update(options)

过滤功能示例:

options = dict(one=1, _two=2)


def update_locals(options, filter_prefix=None):
    print(vars())

    if filter_prefix:
        locals().update(
            {k:v for k,v in options.items() 
             if not k.startswith(filter_prefix)}
        )
    else:
        locals().update(options)  # all
    print(vars(), '\n')


update_locals(options)
update_locals(options, '_')

输出:

{'options': {...}, 'filter_prefix': None}
{'options': {...}, 'filter_prefix': None, 'one': 1, '_two': 2}

{'options': {...}, 'filter_prefix': '_'}
{'options': {...}, 'filter_prefix': '_', 'one': 1}

您可能不需要过滤,因此可以简化该部分。


-1
投票

如果你正在寻找跨 Python 版本的优雅和性能,遗憾的是我认为你不会得到比以下更好的了:

unpack = lambda a,b,c,**kw: (a,b,c) # static

d = dict( a=1, b=2, c=3, d=4, e=5 )

a,b,c = unpack(**d)

工作示例:

>>> unpack = lambda a,b,c,**kw: (a,b,c)
>>> d = dict( a=1, b=2, c=3, d=4, e=5, f=6, g=7 )
>>> a,b,c = unpack(**d)
>>> 
>>> unpack(**d)
(1, 2, 3)

您还可以解压原本会被丢弃的差异:

>>> unpackextra = lambda a,b,c,**kw: (a,b,c,kw)
>>> a,b,c,extra = unpackextra(**d)
>>> 
>>> unpackextra(**d)
(1, 2, 3, {'f': 6, 'd': 4, 'e': 5, 'g': 7})

虽然参数是静态的,所以用例应该特定于您的意图。 ;)

>>> unpack2 = lambda a,b,c,d,e,f,**kw: (a,b,c,d,e,f) # static
>>> 
>>> unpack2(**d)
(1, 2, 3, 4, 5, 6)
>>> 

-2
投票

优雅的解决方案:

d = { "foo": 123, "bar": 456, None: 789 }
foo, bar, baz = d.values()  # 123, 456, 789

请注意,未使用键,因此请确保变量的顺序正确,即它们必须与键插入映射的顺序匹配(自 Python 3.6 起保证了此顺序)。如果对订购有疑问,请使用其他方法。

© www.soinside.com 2019 - 2024. All rights reserved.