自定义索引的数据结构

bpe*_*ter 4 python indexing numpy

我期待写一个数据结构来代表一些遗传数据.这个数据可以表示为一个大小列表n,其中每个条目也有一个"遗传位置",它是0到1之间的实数.为了使术语清晰,我将称之为列表中的位置id和遗传位置gpos.我实现它的方式是作为一个类

class Coords(object):

    def __init__(self, *args, **kwargs):
        self.f = list(*args, **kwargs)
        self.r = dict()
        for i,e in enumerate(self.f):
            self.r[e] = i

    def __setitem__(self,x,y):
        self.f.__setitem__(x,y)
        self.r.__setitem__(y,x)

    def __getitem__(self,x):
        return self.f.__getitem__(x)

    def __len__(self):
        return self.f.__len__()
Run Code Online (Sandbox Code Playgroud)

现在,我有两个问题.第一个是self.r的浮点数是浮点数,这显然是一个坏主意.我在考虑将它们转换为字符串(具有固定数字的数字),但有更好的想法吗?我的另一个问题是我想通过实现访问条目gpos,所以如果我想访问gpos0.2和0.4 之间的所有内容,我希望能够使用

import numpy as np
Coords(np.arange(1,0,-.1))
c.r[0.2:0.4]
Run Code Online (Sandbox Code Playgroud)

是否有一种简单的方法来定义它?我正在考虑id使用二进制搜索找到正确的起始位置和结束位置,然后self.f使用这些ID 进行访问,但有没有办法实现上述语法?

Jai*_*ime 5

使用切片索引对象时,Python会使用slice您提供的输入创建一个对象.例如,如果你这样做c[0.2:0.4],那么传递给的参数c.__getitem__将是slice(0.2, 0.4).所以你可以在你的__getitem__方法中使用类似的代码:

def __getitem__(self, x):
    if isinstance(x, slice):
        start = x.start
        stop = x.stop
        step = x.step
        # Do whatever you want to do to define your return
    ...
Run Code Online (Sandbox Code Playgroud)

如果你想使用这个花哨的索引不在Coords对象上,而是在self.r字典中,我认为最简单的方法是创建FancyIndexDict一个子类dict,修改它的__getitem__方法,然后self.r成为a FancyIndexDict,而不是a dict.

  • 这很酷,我不知道切片符号接受非int参数! (2认同)
  • 实际上我只是尝试了其他数据类型,看起来基本上任何表达都可以工作,甚至像`fancy_obj ['a':('b',8)这样的疯狂] (2认同)