python - 用于从 1 开始索引 python 列表的自定义包装器

标签 python list types operator-overloading wrapper

我想为 python list 类型编写一个简单的包装器,强制它从 1 而不是 0 开始索引。我有一个相当复杂的程序,它基于持续时间数据的一些离散概率分布,具有整数长度的桶,但我没有任何小于 1 的持续时间。无论如何,它会大大简化我代码的一些重要部分能够从 1 开始无缝索引。起初我使用的是 dict,但我发现它们的几个属性太麻烦了。

我以前从未为 Python 类编写过包装器,更不用说内置类型了,但我觉得我想做的事情相当简单。至少,我应该能够做这样的事情:

>>> p = one_list([1,2,3,4,5])
>>> for i in range(1,6):
    print i, p[i]

1 1
2 2
3 3
4 4
5 5
>>> len(p)
5

但是,如果我也可以覆盖 list 类的一些其他相关内置方法,例如 index,那就太好了。

>>> len(p)
5
>>> p.index(p[-1])
5

请分享您的技巧,告诉我如何去做这样的事情。我在考虑是否只用自定义类来做,但这似乎有点过头了。我也欢迎任何关于有用的覆盖方法的建议。

编辑:后记

我只是想指出这样做是不值得的,我接受下面答案的原因不是因为我试图按照他描述的方式实现它,而是因为他帮助了我意识到列表本身就足够了。

最佳答案

这是一个完整的(我认为)基于 1 的列表的实现,正确处理切片(包括扩展切片)、索引、弹出等。要做到这一点比你想象的要复杂一些,尤其是切片和负面指标。事实上,我仍然不能 100% 确定它能正常工作,所以警告编码员。

class list1(list):
    """One-based version of list."""

    def _zerobased(self, i):
        if type(i) is slice:
            return slice(self._zerobased(i.start),
                         self._zerobased(i.stop), i.step)
        else:
            if i is None or i < 0:
                return i
            elif not i:
                raise IndexError("element 0 does not exist in 1-based list")
            return i - 1

    def __getitem__(self, i):
        return list.__getitem__(self, self._zerobased(i))

    def __setitem__(self, i, value):
        list.__setitem__(self, self._zerobased(i), value)

    def __delitem__(self, i):
        list.__delitem__(self, self._zerobased(i))

    def __getslice__(self, i, j):
        print i,j
        return list.__getslice__(self, self._zerobased(i or 1),
                                 self._zerobased(j))

    def __setslice__(self, i, j, value):
        list.__setslice__(self, self._zerobased(i or 1),
                          self._zerobased(j), value)

    def index(self, value, start=1, stop=-1):
        return list.index(self, value, self._zerobased(start),
                          self._zerobased(stop)) + 1

    def pop(self, i):
        return list.pop(self, self._zerobased(i))
不过,

senderle 的 ExtraItemList 将具有更好的性能,因为它不需要不断调整索引,也不需要额外的层(非 C!)方法调用和数据。希望我能想到这种方法;也许我可以将它与我的...结合起来获利...

关于python - 用于从 1 开始索引 python 列表的自定义包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6713463/

相关文章:

python - 如何使用 python API 保存/显示 giphy gif?

r - 如何将列表转换为 r 中的语料库?

C++类型转换

javascript - 限制 Object.fromEntries 的推断类型

python - 从 QML 访问 qresource 文件中的图像

python - 删除 lxml 中的所有命名空间?

python - **在Python中是如何实现的?

ios - 如何在 SwiftUI 的列表中设置和使用参数 "selection"

string - 如何比较两个列表并找出它们之间的差异?

c# - 在 VB、C# 中使用 Linq 处理匿名类型