【Python学习日记】迭代器
class Fib: '''迭代器例子''' def __init__(self, vmax): self.max = vmax def __iter__(self): self.a = 0 self.b = 1 return self def __next__(self): fib = self.a if fib > self.max: raise StopIteration self.a, self.b = self.b, self.a + self.b return fib
类实例创建后,__init__()
方法被立即调用。很容易将其——但技术上来说不正确——称为该类的“构造函数” 。 很容易,因为它看起来很像 C++ 的构造函数(按约定,__init__()
是类中第一个被定义的方法),行为一致(是类的新实例中第一片被执行的代码), 看起来完全一样。 错了, 因为__init__()
方法调用时,对象已经创建了,你已经有了一个合法类对象的引用。
每个方法的第一个参数,包括 __init__()
方法,永远指向当前的类对象。 习惯上,该参数叫 self。 该参数和c++或Java中 this
角色一样, 但 self 不是 Python的保留字, 仅仅是个命名习惯。 虽然如此,请不要取别的名字,只用 self; 这是一个很强的命名习惯。
在 __init__()
方法中, self 指向新创建的对象; 在其他类对象中, 它指向方法所属的实例。尽管需在定义方法时显式指定self ,调用方法时并 不 必须明确指定。 Python 会自动添加。
迭代器工具库
import itertools names = list(open('favorite-people.txt', encoding='gb2312')) print(names) names = [name.rstrip() for name in names] print(names) names = sorted(names) print(names) names = sorted(names, key=len) print(names) groups = itertools.groupby(names, len) print(list(groups)) #调用list() 函数会“耗尽”这个迭代器, #也就是说 你生成了迭代器中所有元素才创造了这个列表。 #迭代器没有“重置”按钮。你一旦耗尽了它,你没法重新开始。 #如果你想要再循环一次(例如, 在接下去的for循环里面), #s你得调用itertools.groupby()来创建一个新的迭代器。 groups = itertools.groupby(names, len) for name_length, name_iter in groups: print('Names with {0:d} letters:'.format(name_length)) for name in name_iter: print(name) def mydef(name): return name[0] groups = itertools.groupby(names, mydef) for name_length, name_iter in groups: print('Names with {0:s} letters:'.format(name_length)) for name in name_iter: print(name)
>>> list(range(0, 3)) [0, 1, 2] >>> list(range(10, 13)) [10, 11, 12] >>> list(itertools.chain(range(0, 3), range(10, 13))) [0, 1, 2, 10, 11, 12] >>> list(zip(range(0, 3), range(10, 13))) [(0, 10), (1, 11), (2, 12)] >>> list(zip(range(0, 3), range(10, 14))) [(0, 10), (1, 11), (2, 12)] >>> list(itertools.zip_longest(range(0, 3), range(10, 14))) [(0, 10), (1, 11), (2, 12), (None, 13)]