我正在python中实现一个Fenwick树类。
基本上我有一个内部列表和两个方法get(key)
和increase(key, inc)
来处理读取和更新此列表。
使用f[5]
可以轻松将f.get(5)
映射到__getitem__
,但有没有办法让f[5] += 2
表示f.increase(5, 2)
?
我发现一个相关的mailing list thread表示除非你将__getitem__
的结果包装在一个实现__iadd__
的代理类中,否则无法完成,但这不是一个选项。所以我可能不得不接受我将不得不使用increase
- 方法,只是想我在这里问一下,以防一些天才有解决方案。
顺便说一句,我正在使用python3.2。
答案 0 :(得分:3)
不,你描述的方法几乎是唯一的选择。可能会有微小的变化,但是f[5] += 2
将调用__getitem__
,然后调用__setitem__
并仅执行+
部分这一事实没有(理智的,至少)方式在检索的对象上,不考虑容器。
答案 1 :(得分:0)
我认为这取决于v
是什么以及您是否可以编辑定义类f
的代码:
对于v
是一个整数的情况,你可以编辑类f的代码,这当然是可能的:
class alist(object):
def __init__(self):
self.L = list()
def append(self, v):
self.L.append(v)
def increase(self, k, i):
self.L[k] += i
def __getitem__(self, k):
return self.L[k]
def __setitem__(self, k, v):
self.L[k] = v
a = alist()
a.append(8)
a.append(1)
a.append(15)
a.append(57)
print "List contains: ", a.L
print "This should be eight: ", a.get(0)
# Increase using the increase method
a.increase(0,2)
print "This should be ten: ", a.get(0)
print "This should be ten: ", a[0]
# Increment using the [] getitem shortcut
a[0] += 2
print "This should be twelve: ", a.get(0)
print "This should be twelve: ", a[0]
print "List contains: ", a.L
显示:
List contains: [8, 1, 15, 57]
This should be eight: 8
This should be ten: 10
This should be ten: 10
This should be twelve: 12
This should be twelve: 12
List contains: [12, 1, 15, 57]
不需要在代理类中包装,也不需要定义__iadd__
,因为它已经为整数定义了。现在,如果您正在使用其他元素数据类型(如自定义对象),则可能需要定义__iadd__
。
答案 2 :(得分:0)
可能是我遗失了一些东西,但为什么你不能在setitem
上调用增加? e.g。
class FTree(object):
def __init__(self):
# could be any data structure, on which get and increase work
self._data = [1,2,3,4]
def get(self, key):
return self._data[key]
def increase(self, key, value):
print "increasing item",key,"by",value
self._data[key] += value
def __getitem__(self, key):
return self.get(key)
def __setitem__(self, key, value):
self.increase(key, value - self.get(key)
f = FTree()
f[2] += 2
print f[2]
输出:
increasing item 2 by 2
5
不是你想要的吗?