2009-11-12 110 views
1

說你有,Python字典簡單的方法來添加一個新的鍵值對

foo = 'bar' 
d = {'a-key':'a-value'} 

而你要

d = {'a-key':'a-value','foo':'bar'} 
e = {'foo':foo} 

我知道你能做到,

d['foo'] = foo 

#Either of the following for e 
e = {'foo':foo} 
e = dict(foo=foo) 

但是,在所有這些將變量foo添加到字典中的方法中,我必須使用foo兩次;一次指示鑰匙,一次指示鑰匙的價值。

對我來說,使用foo兩次似乎很浪費。有一種更簡單的方法,你可以告訴python 「將這個變量添加到字典中,其名稱作爲鍵,其值爲」

+0

你怎麼到達你的'foo ='bar''。有沒有辦法跳過這個狀態?或者有'dict':'{'foo':'bar'}'而不是? – SilentGhost 2009-11-12 12:30:07

回答

2

Actutally使用foo兩次是在Python程序顯着常見的。它被廣泛用於傳遞參數,例如

def f(foo, bar): 
    g(foo=foo) 

這是您的問題中字典操作的特例。

我不認爲有一種避免它的方法,而不訴諸於magic,所以我認爲你必須忍受它。

+0

是的,這絕對是常見的,我想每次都避免它。我的問題,一般涵蓋了這個一般的重複。 – 2009-11-12 12:41:12

2

您可以使用:

name = 'foo' 
d[name] = vars[name] 

我沒有看到你de箱子之間的區別:兩個組「富」到foo的值。

如果你想在一個函數來埋葬這一點,總是存在意外:

def add_variable(d, name): 
    # blah 

因爲那必須使用inspect開始在框架上閒逛。

這聽起來像一個更大的問題,如果你想向我們描述它,可能會有更好的解決方案。例如,如果問題是,你不關心只是富,但事實上,局部變量的整體轉換,那麼也許你想要的東西,如:

d.update(locals()) 

將複製的名稱和值所有的局部變量分爲d

+0

Ned:這是一個常用的django模式,返回render_to_resp('template',{'a':a,'b':b,'c':c})。如果我可以做,render_to_resp('模板',func(a,b,c,d)) – agiliq 2009-11-12 12:32:23

+0

確切地說:那麼'render_to_response('template',locals())'? – 2009-11-12 15:07:47

+0

工作,但允許可能不安全的模板訪問* all * your local變量可能是不可取的 – Wim 2009-11-12 15:19:44

4

你可以做這樣的事情

def add_dry_foo(d, namespace, fooName): 
    d[fooName] = namespace[fooName] 

foo = 'oh-foo' 
d = {} 
add_dry_foo(d, locals(), 'foo') 
print d 
0

你可以使用eval,雖然我不知道,我會推薦它。

>>> d = dict() 
>>> foo = 'wibble' 
>>> def add(d, name): 
     d[name] = eval(name) 


>>> add(d, 'foo') 
>>> d 
{'foo': 'wibble'} 

編輯: 我要指出的,爲什麼我不建議 「EVAL」。如果你做這樣的事情會發生什麼? (來自:http://mail.python.org/pipermail/tutor/2005-November/042854.html

>>> s = "(lambda loop: loop(loop)) (lambda self: self(self))" 
>>> add(d, s) 

Traceback (most recent call last): 
    File "<pyshell#54>", line 1, in <module> 
    add(d, s) 
    File "<pyshell#43>", line 2, in add 
    d[name] = eval(name) 
    File "<string>", line 1, in <module> 
    File "<string>", line 1, in <lambda> 
    File "<string>", line 1, in <lambda> 
    ... 
    File "<string>", line 1, in <lambda> 
RuntimeError: maximum recursion depth exceeded 
1

所有本地變量添加到字典,你可以這樣做:

d.update(locals()) 

的功能相同的作品要求:

func(**locals()) 

請注意,根據你在哪裏locals()威力當然包含在那些不應該出現在字典中的東西。所以,你可以實現一個過濾功能:

def filtered_update(d, namespace): 
    for key, value in namespace.items(): 
     if not key.startswith('__'): 
      d[key] = value 

filtered_update(d, locals()) 

當然Python的理念是「顯勝於隱」,所以一般我都會步行一英里,並用手做這種東西,(否則,您必須注意你的本地命名空間中發生了什麼)。

1

如果你不想通過所有的locals()(這可能是一個安全風險,如果您不完全信任你要發送的數據量太大的功能),一個單行答案可能是這樣的:

dict([ (var, locals()[var]) for var in ['foo', 'bar'] ])

或在Python 3.0,這將成爲可能:

{ var: locals()[var] for var in ['foo', 'bar'] }

+0

+ 1的詞典理解Py3k – 2009-11-12 16:17:59

0

在我看來,你所談論的是一個 提高至p arameter傳遞功能:

def func(*vars): 

提供有序值元組無按鍵

def func(**vars): 

提供了關鍵值對的字典,即 必須爲鍵=值雙傳遞。

def func(***vars): 

將提供關鍵值對的字典, 通過明確地作爲鍵=值, 或隱式地(變量, 文字會導致錯誤而不鍵=

SO:

(x1,x2,x3) = (1,2,3) 
def myfunc(***vars): 
    retrun vars 
myfunc(x1,x2,x3) 
>>> {'x1':1,'x2':2,'x3':3} 

但當然,THI這只是一廂情願的想法......

相關問題