Python变量作为dict的键

Python变量作为dict的键,python,dictionary,Python,Dictionary,在Python(2.7)中有没有一种更简单的方法可以做到这一点:注意:这并不是什么花哨的事情,就像将所有局部变量放入字典一样。只是我在列表中指定的那些 apple = 1 banana = 'f' carrot = 3 fruitdict = {} # I want to set the key equal to variable name, and value equal to variable value # is there a more Pythonic way to get {'ap

在Python(2.7)中有没有一种更简单的方法可以做到这一点:注意:这并不是什么花哨的事情,就像将所有局部变量放入字典一样。只是我在列表中指定的那些

apple = 1
banana = 'f'
carrot = 3
fruitdict = {}

# I want to set the key equal to variable name, and value equal to variable value
# is there a more Pythonic way to get {'apple': 1, 'banana': 'f', 'carrot': 3}?

for x in [apple, banana, carrot]:
    fruitdict[x] = x # (Won't work)
函数返回一个包含所有全局变量的字典

>>> apple = 1
>>> banana = 'f'
>>> carrot = 3
>>> globals()
{'carrot': 3, 'apple': 1, '__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'banana': 'f'}
一个班轮是:-

fruitdict = dict(zip(('apple','banana','carrot'), (1,'f', '3'))

为什么你不做相反的事情:

fruitdict = { 
      'apple':1,
      'banana':'f',
      'carrot':3,
}

locals().update(fruitdict)
更新:

不要使用上面的代码检查注释

顺便问一下,你为什么不标记你想要的VAR,我不知道 也许是这样:

# All the vars that i want to get are followed by _fruit
apple_fruit = 1
carrot_fruit = 'f'

for var in locals():
    if var.endswith('fruit'):
       you_dict.update({var:locals()[var])

这有点,嗯。。。非肾盂。。。丑陋的。。。粗俗的

下面是一段代码,假设您想创建一个包含所有本地变量的字典 在获取特定检查点后创建:

checkpoint = [ 'checkpoint' ] + locals().keys()[:]
## Various local assigments here ...
var_keys_since_checkpoint = set(locals().keys()) - set(checkpoint)
new_vars = dict()
for each in var_keys_since_checkpoint:
   new_vars[each] = locals()[each]
请注意,我们在捕获
locals().keys()
的过程中显式地添加了“checkpoint”键,我也显式地从中获取了一部分,尽管在这种情况下不需要这样做,因为必须展平引用才能将其添加到['checkpoint']列表中。但是,如果您正在使用此代码的变体,并尝试快捷方式输出
['checkpoint']+部分(例如,因为该键已经位于
locals()
)。。。然后,如果没有[:]切片,您可能会得到一个对
locals().keys()`的引用,它的值会随着您添加变量而改变

>>> apple = 1
>>> banana = 'f'
>>> carrot = 3
>>> globals()
{'carrot': 3, 'apple': 1, '__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'banana': 'f'}

一开始,我想不出一种方法来调用像
new\u vars.update()
这样的东西,其中包含要添加/更新的键列表。因此,for
循环的
是最可移植的。我想字典理解可以在Python的最新版本中使用。不过,这似乎只不过是一场代码高尔夫。

这个问题实际上已经得到了回答,但我只想说你说的很有趣

这不是什么花哨的东西,比如 将所有局部变量放入 字典

因为它实际上是“爱好者”

你想要的是:

apple = 1
banana = 'f'
carrot = 3
fruitdict = {}

# I want to set the key equal to variable name, and value equal to variable value
# is there a more Pythonic way to get {'apple': 1, 'banana': 'f', 'carrot': 3}?

names= 'apple banana carrot'.split() # I'm just being lazy for this post
items = globals()                    # or locals()

for name in names:
    fruitdict[name] = items[name]
老实说,您所做的只是将条目从一本词典复制到另一本词典

(格雷格·休吉尔几乎给出了完整的答案,我只是把它完成了)

…就像人们建议的那样,你应该首先把这些放在字典里,但我认为出于某种原因,你不能

a = "something"
randround = {}
randround['A'] = "%s" % a

成功。

根据mouad的答案,这里有一种更为通俗的方法,可以根据前缀选择变量:

# All the vars that I want to get start with fruit_
fruit_apple = 1
fruit_carrot = 'f'
rotten = 666

prefix = 'fruit_'
sourcedict = locals()
fruitdict = { v[len(prefix):] : sourcedict[v]
              for v in sourcedict
              if v.startswith(prefix) }
# fruitdict = {'carrot': 'f', 'apple': 1}

您甚至可以将其放在带有前缀和sourcedict作为参数的函数中。

这里它在一行中,无需重新键入任何变量或其值:

fruitdict.update({k:v for k,v in locals().copy().iteritems() if k[:2] != '__' and k != 'fruitdict'})
尝试:


不是最优雅的解决方案,而且只在90%的时间内有效:

def vardict(*args):
    ns = inspect.stack()[1][0].f_locals
    retval = {}
    for a in args:
        found = False
        for k, v in ns.items():
            if a is v:
                retval[k] = v
                if found:
                    raise ValueError("Value found in more than one local variable: " + str(a))
                found = True
        if found:
            continue
        if 'self' in ns:
            for k, v in ns['self'].__dict__.items():
                if a is v:
                    retval[k] = v
                    if found:
                        raise ValueError("Value found in more than one instance attribute: " + str(a))
                    found = True
        if found:
            continue
        for k, v in globals().items():
            if a is v:
                retval[k] = v
                if found:
                    raise ValueError("Value found in more than one global variable: " + str(a))
                found = True
        assert found, "Couldn't find one of the parameters."
    return retval


如果在多个变量中存储相同的引用,而且如果多个变量存储相同的小int,则会遇到问题,因为这些变量会被插入。

可以在dict中定义变量吗?比如FrootDict=dict(apple=1,banana=2,carrot=3)?不是真的,每个变量都有很多代码,所以它不可读。我想你知道你的代码没有按照你的注释所说的那样编写吗?除非在名称空间字典(如locals()中找到所需的内容,否则无法从对象返回到名称。不过,您可以编写一个函数,在名称空间字典中查找这些变量,并将找到的值分配给该键;见jimbob的答案。是的,对不起,我应该澄清一下。对不起,我一定是在你写答案后编辑的。我只需要我指定的变量,而不是所有的locals()或globals()@Jasie:我添加了一个示例,首先简单地使用字典,而不是乱搞变量。谢谢,但是数字是随机赋值(不需要范围())。更新
locals()
像这样真的很邪恶。正如我的一个朋友所说:“黑暗巫毒”同意,但我对他的问题的理解是,他只想得到水果和豆类;这基本上是不可能的,除非他能教他的程序区分水果、豆类和其他东西,或者也许我只是把事情复杂化了也许他只是想要“胡萝卜、香蕉、苹果”变量:)更新本地人()是被禁止的,所以我想我没有看到jimbob的帖子。。。实际上,同样的事情,就是不要多次调用局部变量/全局变量。我不认为多次调用全局变量实际上会更有效率;id(locals())==id(items)您将获得相等的值。或者如果您执行了items=locals();b=3;items['b']它将找到新的变量b,因为它实际上没有将本地dict复制到items(这会更慢)。如果您完成了items=locals().copy(),则可能会有细微的差异;但是,复制步骤可能也比从locals dict.one-line
dict([(i,locals()[i])中访问少量项慢('apple','banana','carrot')])
虽然这个问题是关于2.7的,但是请注意,上面的一个行在Python 3中不起作用,因为
locals()
显然指出了列表理解的范围。那么Python 3的解决方案是什么呢?@Dr_Zaszuś您在
dict([(i,loc[i])之前设置了
loc=locals()
(i,loc[i]),表示in('apple','banana','carrot')))
{i:loc表示in('apple','banana carrot')}
,无需创建列表并将其转换为dict。它应该是
{'a':'something'}
,您将得到
{'a':'something'}
。。。您正在硬编码按键
A
与简单地执行dict(苹果=苹果,香蕉=香蕉,胡萝卜=胡萝卜)有何不同?
to_dict = lambda **k: k
apple = 1
banana = 'f'
carrot = 3
to_dict(apple=apple, banana=banana, carrot=carrot)
#{'apple': 1, 'banana': 'f', 'carrot': 3}
def vardict(*args):
    ns = inspect.stack()[1][0].f_locals
    retval = {}
    for a in args:
        found = False
        for k, v in ns.items():
            if a is v:
                retval[k] = v
                if found:
                    raise ValueError("Value found in more than one local variable: " + str(a))
                found = True
        if found:
            continue
        if 'self' in ns:
            for k, v in ns['self'].__dict__.items():
                if a is v:
                    retval[k] = v
                    if found:
                        raise ValueError("Value found in more than one instance attribute: " + str(a))
                    found = True
        if found:
            continue
        for k, v in globals().items():
            if a is v:
                retval[k] = v
                if found:
                    raise ValueError("Value found in more than one global variable: " + str(a))
                found = True
        assert found, "Couldn't find one of the parameters."
    return retval