# Python迭代器和生成器

• 1.1 容器
• 1.2 取值
• 3.1 给定一个列表和一个数字，求这个数字的位置
• 3.2 判断第一个子列是不是第二个的子序列
• 3.3 验证

# 1、 迭代器

## 1.1 容器

```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)))

########## 输出 ##########

1234 is iterable? False
1234 is iterable? True
[1, 2, 3, 4] is iterable? True
{1, 2, 3, 4} is iterable? True
{1: 1, 2: 2, 3: 3, 4: 4} is iterable? True
(1, 2, 3, 4) is iterable? True```

## 1.2 取值

```>>> a = iter("123")
>>> next(a)
'1'
>>> next(a)
'2'
>>> next(a)
'3'
>>> next(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration```

# 2、生成器

[i for i in range(1000000000] 它也是一个迭代器，只不会太大了，跑不起来。于是生成器就出来了。

```import os
import psutil

# 显示当前 python 程序占用的内存大小
def show_memory_info(hint):
pid = os.getpid()
p = psutil.Process(pid)

info = p.memory_full_info()
memory = info.uss / 1024. / 1024
print('{} memory used: {} MB'.format(hint, memory))

def test_iterator():
show_memory_info('initing iterator')
list_1 = [i for i in range(100000000)]
show_memory_info('after iterator initiated')
print(sum(list_1))
show_memory_info('after sum called')

def test_generator():
show_memory_info('initing generator')
list_2 = (i for i in range(100000000))
show_memory_info('after generator initiated')
print(sum(list_2))
show_memory_info('after sum called')

%time test_iterator()
%time test_generator()

########## 输出 ##########

initing iterator memory used: 48.9765625 MB
after iterator initiated memory used: 3920.30078125 MB
4999999950000000
after sum called memory used: 3920.3046875 MB
Wall time: 17 s
initing generator memory used: 50.359375 MB
after generator initiated memory used: 50.359375 MB
4999999950000000
after sum called memory used: 50.109375 MB
Wall time: 12.5 s```

yield在scrapy用的多，然后我在其他地方没有见到过。

yield和return也很好区别，return就返回值，结束函数，yield只是保存，不会结束函数。想下，你用scrapy爬错，爬一个就return，不干了，这怎么行。

# 3、 练习

## 3.1 给定一个列表和一个数字，求这个数字的位置

```# 枚举的方法
def index_normal(L, target):
result = []
for i, num in enumerate(L):
if num == target:
result.append(i)
return result

print(index_normal([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2))

########## 输出 ##########

[2, 5, 9]```

```def index_generator(L, target):
for i, num in enumerate(L):
if num == target:
yield i

print(list(index_generator([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2)))

########## 输出 ##########

[2, 5, 9]```

(1 in iter([1,2,3])) # True

```b = (i for i in range(5))  # 生成器

print(2 in b)
print(4 in b)
print(3 in b)

########## 输出 ##########

True
True
True```

## 3.2 判断第一个子列是不是第二个的子序列

```def is_subsequence(a, b):
b = iter(b) # 迭代器
return all(i in b for i in a)

print(is_subsequence([1, 3, 5], [1, 2, 3, 4, 5]))
print(is_subsequence([1, 4, 3], [1, 2, 3, 4, 5]))

########## 输出 ##########

True
False```

## 3.3 验证

```def generator(k):
i = 1
while True:
yield i ** k
i += 1

gen_1 = generator(1)
gen_3 = generator(3)
print(gen_1)
print(gen_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('next_1 = {}, next_3 = {}'.format(next_1, next_3))
sum_1 += next_1
sum_3 += next_3
print(sum_1 * sum_1, sum_3)

get_sum(8)

########## 输出 ##########

<generator object generator at 0x000001E70651C4F8>
<generator object generator at 0x000001E70651C390>
next_1 = 1, next_3 = 1
next_1 = 2, next_3 = 8
next_1 = 3, next_3 = 27
next_1 = 4, next_3 = 64
next_1 = 5, next_3 = 125
next_1 = 6, next_3 = 216
next_1 = 7, next_3 = 343
next_1 = 8, next_3 = 512
1296 1296```

0 条评论

• ### 数据科学篇| Seaborn库的使用（四）

Seaborn是基于matplotlib的图形可视化python包。它提供了一种高度交互式界面，便于用户能够做出各种有吸引力的统计图表。

• ### 机器学习认识聚类（KMeans算法）

导读：机器是怎样学习的，都学到了什么？人类又是怎样教会机器学习的？本文通过案例给你讲清楚各类算法的原理和应用。

• ### 原创 | SpringBoot监听rabbitmq和创建交换器，队列

高级消息队列协议（AMQP）是面向消息的中间件的平台中立的线级协议。Spring AMQP项目将核心Spring概念应用于基于AMQP的消息传递解决方案的开发。...

• ### python3--迭代器，生成器

现在是从结果分析原因，能被for循环的就是"可迭代的"，但是如果按常规想，for怎么知道谁是可迭代的呢？

• ### Python生成器的使用技巧详解

之前我们介绍了列表解析式，他的优点很多，比如运行速度快、编写简单，但是有一点我们不要忘了，他是一次性生成整个列表。如果整个列表非常大，这对内存也同样会造成很大压...

• ### 3.Python迭代器(函数名的应用,新版格式化输出)

​ 函数名的定义和变量的定义几乎一致，在变量的角度，函数名其实就是一个变量，具有变量的功能：可以赋值；但是作为函数名他也有特殊的功能就是加上()就会执行对应的函...

• ### 习题29：循环和列表

创建一个列表使用[]，在里面放入列表的数据，然后用逗号隔开，然后python接收这个列表以及里面所有的内容，将其赋给一个变量

• ### Python条件语句与循环

1、判断与循环 python 缩进 main： print("Hello") print("Hello world.")

• ### python进阶之生成器

可以被for循环的就说明他们是可迭代的，比如：字符串，列表，字典，元祖，们都可以for循环获取里面的数据

• ### python迭代器(函数名的应用,新版格

s1 = 'asdf' obj = iter(s1) #转化为迭代器 print(obj)#<str_iterator object at 0x000002...