MST
星途 面试题库

面试题:Python自定义数据结构索引边界处理的优化

自定义一个类似列表的数据结构 `MyList`,该数据结构支持动态扩容。在实现 `MyList` 类时,需要考虑索引的边界问题,包括正向索引和负向索引(类似Python列表的索引方式)。请编写 `MyList` 类的完整代码,并阐述在实现过程中,针对索引边界检查,你采取了哪些优化策略以提高性能,特别是在处理大规模数据时。
36.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
class MyList:
    def __init__(self, initial_capacity=4):
        self.capacity = initial_capacity
        self.length = 0
        self.data = [None] * self.capacity

    def append(self, value):
        if self.length == self.capacity:
            self._resize()
        self.data[self.length] = value
        self.length += 1

    def _resize(self):
        self.capacity *= 2
        new_data = [None] * self.capacity
        for i in range(self.length):
            new_data[i] = self.data[i]
        self.data = new_data

    def __getitem__(self, index):
        if isinstance(index, slice):
            start, stop, step = index.start, index.stop, index.step
            if start is None:
                start = 0
            if stop is None:
                stop = self.length
            if step is None:
                step = 1
            if start < 0:
                start += self.length
            if stop < 0:
                stop += self.length
            return [self.data[i] for i in range(start, stop, step)]
        else:
            if index < 0:
                index += self.length
            if index < 0 or index >= self.length:
                raise IndexError('list index out of range')
            return self.data[index]

    def __setitem__(self, index, value):
        if index < 0:
            index += self.length
        if index < 0 or index >= self.length:
            raise IndexError('list index out of range')
        self.data[index] = value

    def __len__(self):
        return self.length


索引边界检查的优化策略

  1. 对于正向索引:在 __getitem____setitem__ 方法中,当获取或设置元素时,直接检查索引是否小于0或者大于等于当前列表的长度。如果是,抛出 IndexError 异常。这种检查方式简单直接,对于大规模数据,每次索引操作的时间复杂度是O(1),不会随着数据规模的增大而显著增加额外开销。
  2. 对于负向索引:将负向索引转换为正向索引后再进行边界检查。具体做法是将负向索引值加上列表的长度,这样就得到了对应的正向索引,然后再按照正向索引的检查方式进行检查。这种转换操作同样时间复杂度为O(1),在处理大规模数据时不会带来过多性能负担。
  3. 切片操作:对于切片操作,首先处理切片对象中的 startstopstep 参数,将 None 值替换为默认值。对于负向的 startstop,同样转换为正向索引。最后通过 range 生成切片范围内的索引列表,并获取对应的值。这种处理方式虽然涉及到循环生成索引列表,但整体操作的时间复杂度是线性的,与切片的范围相关,而不是与整个数据规模相关,在大规模数据下也能保持相对较好的性能。