8

我想做这样的事情:

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

但是一直输入这些只是很痛苦,无论如何有别名吗?我知道在 C++ 中可以有一个返回引用的辅助函数,这样你就可以输入:

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

以 F 作为辅助函数。非常感谢!

4

2 回答 2

13

我认为这实际上只能通过子类来实现:

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

产量:

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

__getitem__这引入了和之间的不对称,可以通过以相同方式__setitem__重新定义轻松修复。__getitem__

这可能看起来有点混乱——确实如此。为什么需要子类?这只会使将非frozenset对象作为键放入字典中变得更加困难。不过,您可以轻松地使用此配方创建一个代理对象,该对象将使用您的 dict 执行此操作:

#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]
于 2013-01-21T18:50:07.740 回答
4

在 Python 中没有像 C++ 引用那样的东西,而且您使用的语法在引导时是非法的(用解析器的话来说:)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']
于 2013-01-21T18:51:39.693 回答