2013-01-21 61 views
8

字典操作我想做的事情是這樣的:別名在Python

f[frozenset((1,3,4))] = 5 
f[frozenset((1,))] = 3 

但輸入這些所有的時間,它只是痛苦的,反正是有有別名嗎?我知道在C++中它可能有一個輔助函數返回一個參考,所以你可以只輸入:

F(1,3,4) = 5 
F(1) = 3 

使用F作爲輔助功能。非常感謝!

回答

13

我認爲這實際上只能經由一個子類來實現的:限定重新

{frozenset([1, 2, 3]): 4, frozenset([1]): 5} 

這引入__getitem____setitem__之間的不對稱,其可以很容易地通過被固定:

class FrozenSetDict(dict): 
    def __setitem__(self,idx,value): 
     try: 
      dict.__setitem__(self,frozenset(idx),value) 
     except TypeError: 
      dict.__setitem__(self,frozenset((idx,)),value) 

d = FrozenSetDict() 
d[1,2,3] = 4 
d[1] = 5 
print d 

產量__getitem__以同樣的方式。

這看起來有點麻煩 - 的確如此。爲什麼需要一個子類?這使得將非frozenset對象作爲關鍵字放入字典變得更加困難。你可以很容易地使用這個配方儘管創建一個代理對象可以使你的字典做到這一點:

#I don't like the name of this class -- I'm open to suggestions :) 
class FrozenSetProxy(object): 
    def __init__(self,obj): 
     self.obj = obj 

    def __setitem__(self,idx,value): 
     try: 
      self.obj[frozenset(idx)] = value 
     except TypeError: 
      self.obj[frozenset((idx,))] = value 

    def __getitem__(self,idx): 
     try: 
      return self.obj[frozenset(idx)] 
     except TypeError: 
      return self.obj[frozenset((idx,))] 

d = dict() 
F = FrozenSetProxy(d) 
F[1,2,3] = 4 
F[1] = 5 
print d 
print F[1] 
+0

這是一點點矯枉過正,是不是? – delnan

+0

@mgilson:非常好,儘管可以很好地展示它的用法示例。 –

+0

@delnan - 排序。我沒有看到任何其他方式來獲得OP正在請求的語法。 – mgilson

4

有沒有像C++中的Python參考,並使用語法是非法的啓動(在的話解析器:can't assign to function call)。你可能用對象或子類dict來模擬它來定製它的__getitem__。但是,有一個更簡單,更侵入性的方式:傳遞價值,幫助過,並讓它處理分配:

def blah(f): 
    def F(*args, value): 
     f[frozenset(args)] = value 
    F(1, 3, 4, value=5) 
    F(1, value=3) 

注意,這裏使用一個Python 3功能,關鍵字只有參數。如果你需要它與Python 2時,您可以通過接受**kwdargs模擬調用語法:

def F(*args, **kwds): 
    # optional: check that no other keyword arguments were passed 
    f[frozenset(args)] = kwds['value']