在Python中不存储所有值的算术序列

2 投票
5 回答
1735 浏览
提问于 2025-04-16 05:08

我想表示一个均匀间隔的浮点数数组,也就是一个等差数列,起始值是a0,元素依次是a0、a0 + a1、a0 + 2a1、a0 + 3a1,等等。这个功能是numpy的arange()方法可以做到的,但它似乎会为整个数组分配内存,而我想用一个迭代器类来实现,这个类只存储a0、a1和n(元素的总数,可能会很大)。

在标准的Python包中,有没有现成的东西可以做到这一点?我找不到,所以我继续尝试:

class mylist():
    def __init__(self, n, a0, a1):
        self._n = n
        self._a0 = a0
        self._a1 = a1

    def __getitem__(self, i):
        if i < 0 or i >= self._n:
            raise IndexError
        return self._a0 + i * self._a1

    def __iter__(self):
        self._i = 0
        return self

    def next(self):
        if self._i >= self._n:
            raise StopIteration
        value = self.__getitem__(self._i)
        self._i += 1
        return value

这样做合理吗,还是我在重复造轮子?

5 个回答

1

出于一些可能很明显的原因,当我遍历 mylist 时,使用 for i,x in enumerate(a): print i,a 并没有返回我期待的值,而是返回了一堆对 mylist 实例的引用。我哪里做错了?

问题出在 print i,a 这行代码上。你打印的是 a,也就是一个数组。你应该打印 x,而不是 a。把这一行改成:

print i,x

还有几点建议:

  1. 把你的类名改成大写开头的格式,比如 class MyList 或者 class Mylist
  2. 如果你在使用 Python 2.x,建议继承 object。所以可以写成 class MyList(object): ...
3

其他回答解决了眼前的问题。需要注意的是,如果你只想要一个迭代器,并且不需要随机访问,那么就没必要写一个完整的迭代器类。

def mylist(n, a0, a1):
    for i in xrange(n):
        yield a0 + i*a1
3

首先,你做错了一件事,应该是 for i, x in enumerate(a): print i, x

另外,我可能会建议你用生成器方法,这样就不用麻烦地处理 __iter__next() 这些方法了。特别是因为你的解决方案不允许你同时用两个不同的迭代器遍历同一个 mylist(因为 self._i 是类内部的局部变量)。

这个方法可能更好,它不仅可以让你随机访问,还能提供高效的迭代器。而且支持 inlen 操作符也是个额外的好处哦 :)

class mylist(object):
    def __init__(self, n, a0, a1, eps=1e-8):
        self._n = n
        self._a0 = a0
        self._a1 = a1
        self._eps = eps

    def __contains__(self, x):
        y = float(x - self._a0) / self._a1
        return 0 <= int(y) < self._n and abs(y - int(y)) < self._eps

    def __getitem__(self, i):
        if 0 <= i < self._n:
            return self._a0 + i * self._a1
        raise IndexError

    def __iter__(self):
        current = self._a0
        for i in xrange(self._n):
             yield current
             current += self._a1

    def __len__(self):
        return self._n

撰写回答