Python:实现l[s:e]+=v的正确方法`

2024-10-02 00:31:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在实施一个数据结构,允许快速添加范围更新:

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))

我觉得很奇怪(在原地添加,并设置无论如何?)

那么,S.O.,用什么好的方法来实现这个呢


Tags: andofinlog数据结构supportupdateout
1条回答
网友
1楼 · 发布于 2024-10-02 00:31:08

这是我想到的。做这项工作,但感觉不舒服

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__

相关问题 更多 >

    热门问题