Python菜鸟之路:Python基础-生成器和迭代器、递归
一、迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。迭代器只能往前不会后退。
1. 迭代器优点
对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。本质:迭代器就是生成一个有next()方法的对象,而不是通过索引来计数。
不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。
提供了一个统一的访问集合的接口,只要定义了__iter__()方法对象,就可以使用迭代器访问。
2. 两个基本的方法
1) next方法:返回迭代器的下一个元素
a = {2,3,4,}
b = iter(a)
print(b.__next__())
print(b.__next__())
print(b.__next__())
print(b.__next__()) out:
2
3
4 Traceback (most recent call last):
File "practice3.py", line 216, in <module>
print(b.__next__())
StopIteration
# Ps:从上述例子可以看出,迭代器中元素被访问完毕,如果再次调用__next__方法,会提示StopIteration
2) __iter__方法:返回迭代器对象本身
a = {2,3,4,}
b = iter(a)
print(b.__iter__()) out: <set_iterator object at 0x0000000000B377E0>
3. 迭代器的访问
迭代器对象的访问方法,一般为for循环,循环取出可迭代对象中的元素。在for循环中,Python将自动调用函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。
当然,也可以自己实现一个迭代器,如上所述,只需要在类的__iter__方法中返回一个对象,这个对象拥有一个next()方法,这个方法能在恰当的时候抛出StopIteration异常即可。其中,异常并不是非抛出不可的,不抛出该异常的迭代器将进行无限迭代,某些情况下这样的迭代器很有用。这种情况下,就需要自己判断元素并中止,否则就死循环了!
4. 迭代器的弊端
使用迭代器的循环可以避开索引,这时候内建函数enumerate能在iter函数的结果前加上索引,以元组返回。之前的函数中已经见过这个內建函数的用法。
二、生成器
带有 yield 的函数在 Python 中被称之为 generator,即生成器。
简单地讲,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用函数并不会立即执行函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行函数内部的代码,执行到 yield 时,函数就返回一个迭代值,下次迭代时,代码从上次 yield 位置的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
1. 生成器的优点
生成器是特定的函数,允许你返回一个值,然后“暂停”代码的执行,稍后恢复。生成器使用了“延迟计算”,所以在内存上面更加有效。
2. 生成一个如何判断一个生成器
def num():
a = 1
while a<=5:
yield a
a+=1
a = num() from inspect import isgenerator
from inspect import isgeneratorfunction
# 判断对象是一个生成器
print(isgenerator(a))
out: True
# 判断函数是一个生成器函数
print(isgeneratorfunction(num))
out: True
3. 生成器利用案例
文件读取:如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取
def read_file(fpath):
BLOCK_SIZE = 1024
with open(fpath, 'rb') as f:
while True:
block = f.read(BLOCK_SIZE)
if block:
yield block
else:
return
三、 相关库
Python内置了一个模块itertools,包含了很多函数用于creating iterators for efficient looping(创建更有效率的循环迭代器)。该方法通常返回一个迭代器,可以通过for循环取值。
# encoding: utf-8
# module itertools
# from (built-in)
# by generator 1.138
"""
Functional tools for creating and using iterators. Infinite iterators: #无限迭代
count(start=0, step=1) --> start, start+step, start+2*step, ...
#从start开始,以后每个元素都加上step。step默认值为1,count(10) --> 10 11 12 13 14 ...
cycle(p) --> p0, p1, ... plast, p0, p1, ...
#迭代至序列p的最后一个元素后,从p的第一个元素重新开始 cycle('ABCD') --> A B C D A B C D ...
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times
#将elem重复n次。如果不指定n,则无限重复 repeat(10, 3) --> 10 10 10 Iterators terminating on the shortest input sequence: #在最短的序列参数终止时停止迭代
accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2
#从第一个元素开始,依次累加,accumulate([1,2,3,4,5,6,7.....]) --> 1,3,6,10,15,21,28...
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...
#迭代至序列p的最后一个元素后,从q的第一个元素开始,直到所有序列终止 chain("ABC","BBC"):--> A B C B B C
chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...
#迭代至序列p的最后一个元素后,从q的第一个元素开始,直到所有序列终止p,q都是可迭代对象,比如str: chain.from_iterable(["ABC","BBC"]) --> A B C B B C...
compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...
#如果bool(selectors[n])为True,则next()返回data[n],否则跳过data[n]。
dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails
#当pred对seq[n]的调用返回False时才开始迭代 dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)
#这个函数功能类似于SQL的分组。使用groupby前,首先需要使用相同的keyfunc对iterable进行排序,比如调用内建的sorted函数。然后,groupby返回迭代器,每次迭代的元素是元组(key值, iterable中具有相同key值的元素的集合的子迭代器) groupby([0, 0, 0, 1, 1, 1, 2, 2, 2]) --> (0, (0 0 0)) (1, (1 1 1)) (2, (2 2 2))
filterfalse(pred, seq) --> elements of seq where pred(elem) is False
#如果序列sql中的元素,带入函数pred[seq[0]]返回False,则返回序列中的这个值 filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
islice(seq, [start,] stop [, step]) --> elements from seq[start:stop:step]
#list(itertools.islice(range(100), 1, 10, 2)) --> [1, 3, 5, 7, 9]
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
# 将seq的每个元素以变长参数(*args)的形式调用func, starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n
# 返回n个迭代器it的复制迭代器。
takewhile(pred, seq) --> seq[0], seq[1], until pred fails
# dropwhile的相反版本 takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...
#zip的取最长序列的版本,短序列将填入fillvalue。 Combinatoric generators:# 组合迭代器
product(p, q, ... [repeat=1]) --> cartesian product
# 笛卡尔积 print(list(itertools.product('ABC', repeat=2))) -> [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')]
permutations(p[, r])
# 去除重复的元素 print(list(itertools.permutations('ABC', 2)))-->[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
combinations(p, r)
# 排序后去重print(list(itertools.combinations('ABC', 2))) -> [('A', 'B'), ('A', 'C'), ('B', 'C')]
combinations_with_replacement(p, r)
# 排序后,包含重复元素 print(list(itertools.combinations_with_replacement('ABC', 2)))->[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
"""
# no imports # functions def tee(iterable, n=2): # real signature unknown; restored from __doc__
""" tee(iterable, n=2) --> tuple of n independent iterators. """
pass # classes class accumulate(object):
"""
accumulate(iterable[, func]) --> accumulate object Return series of accumulated sums (or other binary function results).
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable, func=None): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass 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.
"""
@classmethod
def from_iterable(cls, iterable): # real signature unknown; restored from __doc__
"""
chain.from_iterable(iterable) --> chain object Alternate chain() contructor taking a single iterable argument
that evaluates lazily.
"""
pass def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, *iterables): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass 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 __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable, r): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass def __sizeof__(self, *args, **kwargs): # real signature unknown
""" Returns size in memory, in bytes. """
pass 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 __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable, r): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass def __sizeof__(self, *args, **kwargs): # real signature unknown
""" Returns size in memory, in bytes. """
pass class compress(object):
"""
compress(data, selectors) --> iterator over selected data Return data elements corresponding to true selector elements.
Forms a shorter iterator from selected data elements using the
selectors to choose the data elements.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, data, selectors): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass class count(object):
"""
count(start=0, step=1) --> count object Return a count object whose .__next__() method returns consecutive values.
Equivalent to: def count(firstval=0, step=1):
x = firstval
while 1:
yield x
x += step
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, start=0, step=1): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass class cycle(object):
"""
cycle(iterable) --> cycle object Return elements from the iterable until it is exhausted.
Then repeat the sequence indefinitely.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass class dropwhile(object):
"""
dropwhile(predicate, iterable) --> dropwhile object Drop items from the iterable while predicate(item) is true.
Afterwards, return every element until the iterable is exhausted.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, predicate, iterable): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass class filterfalse(object):
"""
filterfalse(function or None, sequence) --> filterfalse object Return those items of sequence for which function(item) is false.
If function is None, return the items that are false.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, function_or_None, sequence): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass class groupby(object):
"""
groupby(iterable[, keyfunc]) -> create an iterator which returns
(key, sub-iterator) grouped by each value of key(value).
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable, key=None): # known case of itertools.groupby.__init__
""" Initialize self. See help(type(self)) for accurate signature. """
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass class islice(object):
"""
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 __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable, stop): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass 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 __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iterable, r=None): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass def __sizeof__(self, *args, **kwargs): # real signature unknown
""" Returns size in memory, in bytes. """
pass class product(object):
"""
product(*iterables, repeat=1) --> product object Cartesian product of input iterables. Equivalent to nested for-loops. For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).
The leftmost iterators are in the outermost for-loop, so the output tuples
cycle in a manner similar to an odometer (with the rightmost element changing
on every iteration). To compute the product of an iterable with itself, specify the number
of repetitions with the optional repeat keyword argument. For example,
product(A, repeat=4) means the same as product(A, A, A, A). product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)
product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, *iterables, repeat=1): # known case of itertools.product.__init__
""" Initialize self. See help(type(self)) for accurate signature. """
return [] def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass def __sizeof__(self, *args, **kwargs): # real signature unknown
""" Returns size in memory, in bytes. """
pass class repeat(object):
"""
repeat(object [,times]) -> create an iterator which returns the object
for the specified number of times. If not specified, returns the object
endlessly.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, p_object, times=None): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass def __length_hint__(self, *args, **kwargs): # real signature unknown
""" Private method returning an estimate of len(list(it)). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass class starmap(object):
"""
starmap(function, sequence) --> starmap object Return an iterator whose values are returned from the function evaluated
with an argument tuple taken from the given sequence.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, function, sequence): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass class takewhile(object):
"""
takewhile(predicate, iterable) --> takewhile object Return successive entries from an iterable as long as the
predicate evaluates to true for each entry.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, predicate, iterable): # real signature unknown; restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass class zip_longest(object):
"""
zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object Return an zip_longest object whose .__next__() method returns a tuple where
the i-th element comes from the i-th iterable argument. The .__next__()
method continues until the longest iterable in the argument sequence
is exhausted and then it raises StopIteration. When the shorter iterables
are exhausted, the fillvalue is substituted in their place. The fillvalue
defaults to None or can be specified by a keyword argument.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, iter1, iter2=None, *some, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass class _grouper(object):
# no doc
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, *args, **kwargs): # real signature unknown
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass class _tee(object):
""" Iterator wrapped to make it copyable """
def __copy__(self, *args, **kwargs): # real signature unknown
""" Returns an independent iterator. """
pass def __init__(self, *args, **kwargs): # real signature unknown
pass def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass def __setstate__(self, *args, **kwargs): # real signature unknown
""" Set state information for unpickling. """
pass class _tee_dataobject(object):
""" Data container common to multiple tee objects. """
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(self, *args, **kwargs): # real signature unknown
pass @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass class __loader__(object):
"""
Meta path import for built-in modules. All methods are either class or static methods to avoid the need to
instantiate the class.
"""
@classmethod
def create_module(cls, *args, **kwargs): # real signature unknown
""" Create a built-in module """
pass @classmethod
def exec_module(cls, *args, **kwargs): # real signature unknown
""" Exec a built-in module """
pass @classmethod
def find_module(cls, *args, **kwargs): # real signature unknown
"""
Find the built-in module. If 'path' is ever specified then the search is considered a failure. This method is deprecated. Use find_spec() instead.
"""
pass @classmethod
def find_spec(cls, *args, **kwargs): # real signature unknown
pass @classmethod
def get_code(cls, *args, **kwargs): # real signature unknown
""" Return None as built-in modules do not have code objects. """
pass @classmethod
def get_source(cls, *args, **kwargs): # real signature unknown
""" Return None as built-in modules do not have source code. """
pass @classmethod
def is_package(cls, *args, **kwargs): # real signature unknown
""" Return False as built-in modules are never packages. """
pass @classmethod
def load_module(cls, *args, **kwargs): # real signature unknown
"""
Load the specified module into sys.modules and return it. This method is deprecated. Use loader.exec_module instead.
"""
pass def module_repr(module): # reliably restored by inspect
"""
Return repr for the module. The method is deprecated. The import machinery does the job itself.
"""
pass def __init__(self, *args, **kwargs): # real signature unknown
pass __weakref__ = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
"""list of weak references to the object (if defined)""" __dict__ = None # (!) real value is '' # variables with complex values __spec__ = None # (!) real value is ''
itertools.source
四、递归
1. 递归的概念
(1)递归就是在过程或函数里调用自身;
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
2. 可以解决的问题
(1)数据的定义是按递归定义的。(比如Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(比如树的遍历,图的搜索)
递归的优点:定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
递归的缺点:递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等
3. 递归函数的创建
- 初始化算法。递归程序通常需要一个开始时使用的种子值(seed value)。要完成此任务,可以向函数传递参数,或者提供一个入口函数,这个函数是非递归的,但可以为递归计算设置种子值。
- 检查要处理的当前值是否已经与基线条件相匹配(base case)。如果匹配,则进行处理并返回值。
- 使用更小的或更简单的子问题(或多个子问题)来重新定义答案。
- 对子问题运行算法。
- 将结果合并入答案的表达式。
- 返回结果。
4. 递归函数的注意事项
基线条件(base case)。基线条件是递归程序的最底层位置,在此位置时没有必要再进行操作,可以直接返回一个结果。所有递归函数都必须至少拥有一个基线条件,而且必须确保它们最终会达到某个基线条件;否则,程序将永远运行下去,直到程序缺少内存或者栈空间。因此,使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。下面看一个溢出的案例:
def fact(n):
if n==1:
return 1
return n * fact(n - 1) fact(1000)
out:
RecursionError: maximum recursion depth exceeded in comparison
5. 解决递归栈溢出
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
6. 经典案例
下面是一个未进行尾递归优化的递归函数
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
下面是进行了尾递归优化的函数(主要是要把每一步的乘积传入到递归函数中)
def fact(n):
return fact_iter(1, 1, n) def fact_iter(product, count, max):
if count > max:
return product
return fact_iter(product * count, count + 1, max)
可以看到,return fact_iter(product * count, count + 1, max)仅返回递归函数本身,product * count和count + 1在函数调用前就会被计算,不影响函数调用。
尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。但是可以通过下面使用装饰器的方式来进行优化↓↓↓
7. 一个py3的尾递归优化的装饰器:
import sys class TailRecurseException(BaseException):
def __init__(self, args, kwargs):
self.args = args
self.kwargs = kwargs def tail_call_optimized(g):
"""
This function decorates a function with tail call
optimization. It does this by throwing an exception
if it is it's own grandparent, and catching such
exceptions to fake the tail call optimization. This function fails if the decorated
function recurses in a non-tail context.
"""
def func(*args, **kwargs):
# 获取当前栈信息
f = sys._getframe()
if f.f_back and f.f_back.f_back \
and f.f_back.f_back.f_code == f.f_code:
raise TailRecurseException(args, kwargs)
else:
while 1:
try:
return g(*args, **kwargs)
except TailRecurseException as e:
args = e.args
kwargs = e.kwargs
func.__doc__ = g.__doc__
return func @tail_call_optimized
def factorial(n, acc=1):
"calculate a factorial"
if n == 0:
return acc
return factorial(n-1, n*acc) print(factorial(1000))
out: 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
# prints a big, big number,
# but doesn't hit the recursion limit. @tail_call_optimized
def fib(i, current = 0, next = 1):
if i == 0:
return current
else:
return fib(i - 1, next, current + next) print(fib(1000))
out: 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
Python菜鸟之路:Python基础-生成器和迭代器、递归的更多相关文章
- python学习之路 七 :生成器、迭代器
本节重点: 掌握列表生成式.生成器.迭代器 一.生成式 现在有个需求,把[1,2,3,4,5,6,7,8,9,10]中的每个值加1. # 二逼青年版 a = [0,1,2,3,4,5,6,7,8,9 ...
- python学习之路-day2-pyth基础2
一. 模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...
- Python菜鸟之路:Django 路由补充1:FBV和CBV - 补充2:url默认参数
一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...
- Python学习之路-Day2-Python基础2
Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...
- Python学习之路-Day1-Python基础
学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...
- PYTHON学习之路_PYTHON基础(1)
学习内容: 1.Python介绍 2.Python程序初接触和变量 3.Python用户交互 4.Python数据类型 5.Python循环if...(elif)...else 6.Python循环w ...
- python学习之路-day1-python基础1
本节内容: Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else ...
- Python学习之路-Day2-Python基础3
Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...
- Python学习之路1 - 基础入门
本文内容 Python介绍 安装Python解释器 输出 变量 输入 条件判断语句 循环语句 模块讲解 三元运算 字符串和二进制的相互转化 本系列文章使用的Python版本为3.6.2 使用开发工具为 ...
- PYTHON学习之路_PYTHON基础(4)
学习内容: 1.Python函数的基本语法 2.Python函数的返回值与变量 3.Python嵌套函数 4.Python递归函数及实例(二分查找) 5.Python匿名函数 6.Python内置方法 ...
随机推荐
- Linux组件封装(三)使用面向对象编程封装Thread
C++11提供了thread,但是过于复杂,我们还是倾向于在项目中编写自己的Thread. Posix Thread的使用这里不再赘述. 重点是这个函数: #include <pthread.h ...
- (九)Thymeleaf用法——Themeleaf注释
4. 注释 模板名称:comment.html 4.1 标准 HTML/XML注释 语法:<!-- --> 4.2 解析器级注释块(Parser-level ...
- Android中ListView分类
1 http://my.oschina.net/bv10000/blog/106436 2
- Android 函数回调
1 http://blog.csdn.net/xyz_lmn/article/details/8631195 我感觉fragment和activity的通信形象的解释了函数的回调,看别人的博客越看越迷 ...
- angular中通过CSS使下拉列表默认值变灰
angular版本:angular5 先看效果图: drop down的样式是我用CSS样式控制的,没有用插件.想要改变Drop Down List里的默认值的颜色,我的思路是这样的. 在<se ...
- Atitit.struts排除url 的设计and 原理 自定义filter 排除特定url
Atitit.struts排除url 的设计and 原理 自定义filter 排除特定url 1.1. 原理流程1 2. Invoke1 3. StrutsX2 1.1. 原理流程 读取struts配 ...
- 浅谈C/C++堆栈指引——C/C++堆栈
C/C++堆栈指引 Binhua Liu 前言 我们经常会讨论这种问题:什么时候数据存储在飞鸽传书堆栈(Stack)中.什么时候数据存储在堆(Heap)中.我们知道.局部变量是存储在堆栈中的.debu ...
- Ubuntu 16.04主题美化和软件推荐
http://www.linuxidc.com/Linux/2016-09/135165.htm http://www.techweb.com.cn/network/system/2015-11-20 ...
- MySQL中in(常量列表)的执行计划
我们在写sql的时候,经常用到in,in后面跟一堆常量列表,如id.有人说in的效率很高,而有人说很低:有人说in能使用索引,还有人说in不能使用索引... 到底是一个怎样的情况呢?我们分析以下几种情 ...
- iOS swift NSClassFromString将字符串转换成类名
在oc中将字符串转换成类名直接调用NSClassFromString("classname")即可,但是到了swift中变的麻烦多了 swift中如果要将字符串转换为类型需要以下几 ...