"""
迭代器(iterator)提供了一个 next 的方法。调用这个方法后,你要么得到这
个容器的下一个对象,要么得到一个 StopIteration 的错误(苹果卖完了)。你不需要像列
表一样指定元素的索引,因为字典和集合这样的容器并没有索引一说。比如,字典采用哈希
表实现,那么你就只需要知道,next 函数可以不重复不遗漏地一个一个拿到所有元素即
可。
而可迭代对象,通过 iter() 函数返回一个迭代器,再通过 next() 函数就可以实现遍历。for
in 语句将这个过程隐式化,所以,你只需要知道它大概做了什么就行了
生成器是懒人版本的迭代器
我们知道,在迭代器中,如果我们想要枚举它的元素,这些元素需要事先生成
生成器,在你调用 next() 函数的时候,才会生成下一个变量。生成
器在 Python 的写法是用小括号括起来,(i for i in range(100000000)),即初始
化了一个生成器。
生成器并不会像迭代器一样占用大量内存,只有在被使用的
时候才会调用。而且生成器在初始化的时候,并不需要运行一次生成操作
"""
def is_iterable(param):
try:
iter(param)
return True
except TypeError:
return False
params = [
1234,
'1234',
[1, 2, 3, 4],
set([1, 2, 3, 4]),
{1: 1, 2: 2, 3: 3, 4: 4},
(1, 2, 3, 4)
]
for param in params:
print('{} is iterable? {}'.format(param, is_iterable(param)))
"""
yield 是魔术的关键。对于初学者来说,你可以理解为,函数运行到这一行的时
候,程序会从这里暂停,然后跳出,不过跳到哪里呢?答案是 next() 函数。那么 i ** k
是干什么的呢?它其实成了 next() 函数的返回值。
这样,每次 next(gen) 函数被调用的时候,暂停的程序就又复活了,从 yield 这里向下继
续执行;同时注意,局部变量 i 并没有被清除掉,而是会继续累加。我们可以看到 next_1
从 1 变到 8,next_3 从 1 变到 512
"""
def generator(k):
i = 1
while True:
yield i ** k
i += 1
gen_1 = generator(1)
gen_3 = generator(3)
def get_sum(n):
sum_1, sum_3 = 0, 0
for i in range(n):
next_1 = next(gen_1)
next_3 = next(gen_3)
print(f'next_1 = {next_1}, next_3 = {next_3}')
sum_1 += next_1
sum_3 += next_3
print(sum_1 * sum_1, sum_3)
get_sum(8)
def index_normal(source_list, target):
"""
普通方法实现列表中找对应数的位置
:param source_list:
:param target:
:return:
"""
result = []
for i, num in enumerate(source_list):
if num == target:
result.append(i)
return result
print(index_normal([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2))
def index_generator(source_list, target):
"""
生成器方法实现列表中找对应数的位置
:param source_list:
:param target:
:return:
"""
for i, num in enumerate(source_list):
if num == target:
yield i
print(list(index_generator([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2)))
def is_subsequence(child_list, father_list):
# 转换成迭代器,可以利用next()可以保存指针位置的特性,从而确保子序列中元素的顺序
father_list = iter(father_list) # 得到迭代器
return all(i in father_list for i in child_list) # 所有的都是True 返回True,否则返回False
print(is_subsequence([1, 3, 5], [1, 2, 3, 4, 5]))
print(is_subsequence([1, 4, 3], [1, 2, 3, 4, 5]))
"""
i in b 等价于:
while True:
val = next(b)
if val == i:
yield True
"""
b = (i for i in range(5))
print(2 in b) # True
print(4 in b) # True
print(3 in b) # False
"""
容器是可迭代对象,可迭代对象调用 iter() 函数,可以得到一个迭代器。迭代器可以通
过 next() 函数来得到下一个元素,从而支持遍历。
生成器是一种特殊的迭代器(注意这个逻辑关系反之不成立)。使用生成器,你可以写
出来更加清晰的代码;合理使用生成器,可以降低内存占用、优化程序结构、提高程序
速度。
生成器只能遍历一次,继续调用 next() 会 raise StopIteration。只有复位生
成器才能重新进行遍历
"""
python 学习:迭代器,生成器
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 主要介绍python的一些高级特性,即列表生成式、生成器、迭代器。 列表生成式 列表生成式即List Compre...
- 列表生成式 写列表生成式时,把要生成的元素 x * x 放到前面,后面跟 for 循环:image.pngfor循...
- 装饰器 在不修改函源代码和调用方式的情况下给函数加上新的功能 无参数的装饰器: out:in the fooin ...
- 装饰器 装饰器本质是一个python函数,它可以在让其他函数不需要任何代码变动的前提下增加额外的功能,装饰器的返回...