我实现了有趣和有利的数据结构,允许快速添加剂范围更新:
class RAUQ:
""" Allow 'l[s:e] += v' update and 'a[i]' query in O(log n)
>>> l = RAUQ([0, 10, 20]) ; l
[0, 10, 20]
>>> l[1]
10
>>> l[2] += 10 ; l
[0, 10, 30]
>>> l[0:2] += 3 ; l
[3, 13, 30]
>>> l[1:10] -= 4 ; l # Support usual out of bounds slices
[3, 9, 26]
"""
根据反汇编的字节码,l[i] += v
表达式转换为:
l.__setitem__(i, l.__getitem__(i).__iadd__(v))
我觉得很奇怪(inplace add,并设置无论如何?)。
那么,S.O.,这将是一个很好的和pythonic方式实现这个?
答案 0 :(得分:1)
这是我想出的。这份工作,但感觉很讨人喜欢。
class RAUQ:
def __init__(self, iterable):
# Stripped down example,
# actual implementation use segment tree.
self.l = list(iterable)
def __getitem__(self, i):
if isinstance(i, slice):
return _view(self, i)
return self.l[i]
def __setitem__(self, i, val):
if isinstance(i, slice):
""" No-op: work already done in view"""
return self
self.l[i] = val
return self
def __str__(self):
return str(_view(self, slice(None)))
__repr__ = __str__
class _view:
def __init__(self, parent, i):
# generic implementation non designed for single index.
assert isinstance(i, slice)
self.l = parent.l
self.i = i
def __iter__(self):
return iter(self.l[self.i])
def update(self, val):
""" Add val to all element of the view """
self.l[self.i] = [x+val for x in self]
def __iadd__(self, val):
self.update(val)
return self
def __isub__(self, val):
self.update(-val)
return self
def __str__(self):
return str(list(self))
__repr__ = __str__