模拟实现一个enumerate函数
1 2 3 4 5 6
| def myEnumerate(seq, start=0): results = [] n = start for i in seq: results.append((n, i)) return results
|
返回一个list, 如果list数据过多,则占用内存太大。而迭代器每次只需要很小的内存。再往下看迭代器。
迭代器
内建函数iter()可以生成一个iterator迭代器。相比list来说,iterator不需要很大的内存空间。
迭代器通过next()来遍历元素,并且完成遍历时抛出StopIteration()异常。
1 2 3 4 5 6 7 8
| it = iter(range(5)) print it.next() print it.next() print it.next() print it.next() print it.next()
print it.next()
|
可以用for循环对迭代器进行遍历
1 2 3 4 5
| it = iter(range(5)) for i in it: print i
print it.next()
|
遍历完成时,调用it.next(),抛出StopIteration()异常。可以看出for循环调用的是next()方法。就像下边这样。
1 2 3 4 5
| while True: try: print it.next() except StopIteration: break
|
用迭代器改进enumerate的实现
一个类只要实现了iter与next()方法, 便可以进行迭代。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class myEnumerate: def __init__(self, seq, start=0): self.seq = seq self.start = start self.n = 0
def __iter__(self): return self
def next(self): if self.n == len(self.seq): raise StopIteration() item = self.seq[self.n] index = self.start self.n += 1 self.start += 1 return index, item
|
使用迭代器解决了空间占用的问题,不过代码也太繁琐了,一点没有python风格。
yield
于是,简洁的代码便来了。一个可迭代的并且简洁的简洁的方案。使用next()方法会依次返回元素,并且越界时报StopIteration异常。
1 2 3 4 5 6 7 8 9 10 11 12 13
| def myEnumerate(seq, start=0): n = start for i in seq: yield n, i n += 1
it = myEnumerate(range(5)) print it.next() print it.next() print it.next() print it.next() print it.next() print it.next()
|