迭代器:
概念: 迭代器可以理解为是一个对象的容器,可迭代对象就是容器里面的对象,迭代器与for循环有很大相似的地方,但是迭代器被遍历的次数是有限,而且是单线的,也就是说迭代一个列表、元组、字典、集合、字符串的时候,每个元素只能取一次,而且要遵循迭代对象的顺序,当迭代对象全部被取出时,再次迭代就会抛异常。
可迭代的内部都有__iter__方法
iter.next():返回迭代器的下一个元素,但没有下一个元素时抛出StopIteration异常。
要注意的是如果可迭代对象元素很多的话,将其预先转换为一个列表要消耗大量的内存。
优点:
- 按顺序取,会把所有的值都取到,不存在遗漏。
- 节省内存空间,迭代器不会占用太多内存,调用一次next生成相对应一个元素,只占一个元素的内存大小。
cookbook:
你想遍历一个可迭代对象中的所有元素,但是却不想使用for循环。就可以迭代啦!为了手动的遍历可迭代对象,使用 next()
函数并在代码中捕获了 StopIteration
异常,就说明已经把容器内所有的元素已经取出, StopIteration
用来指示迭代的结尾。
生成器:
跟普通函数不同的是,生成器只能用于迭代操作。一个生成器函数主要特征是它只会回应在迭代中使用到的 *next* 操作。 一旦生成器函数返回退出,迭代终止。 在 `__iter__()` 方法中定义你的生成器不会改变你任何的算法逻辑。
yield
语句即可将其转换为一个生成器。
itertools库:
1、函数 itertools.islice()
正好适用于在迭代器和生成器上做切片操作。函数 islice()
返回一个可以生成指定元素的迭代器,它通过遍历并丢弃直到切片开始索引位置的所有元素。 然后才开始一个个的返回元素,并直到切片结束索引位置。着重强调的一点是 islice()
会消耗掉传入的迭代器中的数据。 必须考虑到迭代器是不可逆的这个事实。所以如果你需要之后再次访问这个迭代器的话,那你就得先将它里面的数据放入一个列表中。
class islice(object):
"""
# islice()可以用来切片的, None可以表示头或尾
# islice(迭代对象,头,尾)
islice(iterable, stop) --> islice object
islice(iterable, start, stop[, step]) --> islice object
Return an iterator whose next() method returns selected values from an
iterable. If start is specified, will skip all preceding elements;
otherwise, start defaults to zero. Step defaults to one. If
specified as another value, step determines how many values are
skipped between successive calls. Works like a slice() on a list
but returns an iterator.
"""
def __init__(self, iterable, stop): # real signature unknown; restored from __doc__
2、itertools.chain()
可以连接多个列表或者迭代器,接受一个或多个可迭代对象作为输入参数。 然后创建一个迭代器,依次连续的返回每个可迭代对象中的元素。 这种方式要比先将序列合并再迭代要高效的多。chian() 不会要求参数的类型一致,所以如果输入序列非常大的时候会很省内存。 并且当可迭代对象类型不一样的时候 chain() 同样可以很好的工作。
class chain(object):
"""
chain(*iterables) --> chain object
Return a chain object whose .__next__() method returns elements from the
first iterable until it is exhausted, then elements from the next
iterable, until all of the iterables are exhausted.
"""
def __init__(self, *iterables): # real signature unknown; restored from __doc__
3、itertools.permutations()
, 它接受一个集合并产生一个元组序列,每个元组由集合中所有元素的一个可能排列组成。 也就是说通过打乱集合中元素排列顺序生成一个元组,
class permutations(object):
"""
permutations(iterable[, r]) --> permutations object
Return successive r-length permutations of elements in the iterable.
permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
"""
def __init__(self, iterable, r=None): # real signature unknown; restored from __doc__
4、itertools.combinations()
, 对于 combinations() 来讲,元素的顺序已经不重要了。也就是说,组合 ('a', 'b') 跟 ('b', 'a') 其实是一样的(最终只会输出其中一个)。
class combinations(object):
"""
combinations(iterable, r) --> combinations object
Return successive r-length combinations of elements in the iterable.
combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)
"""
def __init__(self, iterable, r): # real signature unknown; restored from __doc__
5、itertools.combinations_with_replacement()
, 允许同一个元素被选择多次
class combinations_with_replacement(object):
"""
combinations_with_replacement(iterable, r) --> combinations_with_replacement object
Return successive r-length combinations of elements in the iterable
allowing individual elements to have successive repeats.
combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
"""
def __init__(self, iterable, r): # real signature unknown; restored from __doc__