python 迭代器和生成器

二者区别

1、共同点

  • 生成器是一种特殊的迭代器

2、不同点

a、语法上

  • 生成器是通过函数的形式中调用 yield 或()的形式创建的
  • 迭代器可以通过 iter() 内置函数创建

b、用法上

  • 生成器在调用next()函数或for循环中,所有过程被执行,且返回值
  • 迭代器在调用next()函数或for循环中,所有值被返回,没有其他过程或动作。

Python可迭代对象,迭代器,生成器的区别

iter() 函数和next()函数

iter() 函数用来生成迭代器。

next() 返回迭代器的下一个项目。

next() 函数要和生成迭代器的iter() 函数一起使用。

如果你在迭代操作时不使用for循环语句,那么你得先调用iter() 函数
 

In [1]: lst=[1,2,3,4]

In [2]: it=iter(lst)

In [3]: next(it)
Out[3]: 1

In [4]: next(it)
Out[4]: 2

In [5]: next(it)
Out[5]: 3

In [6]: next(it)
Out[6]: 4

In [7]: next(it)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-7-bc1ab118995a> in <module>
----> 1 next(it)

StopIteration:

可以在类中__iter__() 内置方法内实现迭代操作

yield 关键字

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

可以用for循环迭代它或者使用其他接受一个可迭代对象的函数(比如 sum() , list() 等)
 

In [2]: def frange(start, stop, increment):
   ...:     x = start
   ...:     while x < stop:
   ...:         yield x
   ...:         x += increment

In [3]: for n in frange(0, 4, 0.5):
   ...:     print(n)
   ...:
0
0.5
1.0
1.5
2.0
2.5
3.0
3.5

In [4]: list(frange(0, 1, 0.125))
Out[4]: [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875]

yield from后面加上可迭代对象,他可以把可迭代对象里的每个元素一个一个的yield出来,对比yield来说代码更加简洁,结构更加清晰。

reversed()函数

reversed()函数用于反向迭代一个序列

反向迭代仅仅当对象的大小可预先确定或者对象实现了 __reversed__() 的特殊方法时才能生效。 如果两者都不符合,那你必须先将对象转换为一个列表才行,比如
 

f = open('somefile')
for line in reversed(list(f)):
    print(line, end='')

可以通过在自定义类上实现 __reversed__() 方法来实现反向迭代


迭代器切片

函数 itertools.islice() 适用于在迭代器和生成器上做切片操作

In [7]: def count(n):
   ...:     while True:
   ...:         yield n
   ...:         n+=1
   ...:

In [8]: import itertools
In [10]: c=count(0)

In [11]: for x in itertools.islice(c, 10,14):
    ...:     print(x)
    ...:
10
11
12
13

排列组合迭代

itertools.permutations() ,接受一个集合并产生一个元组序列,每个元组由集合中所有元素的一个可能排列组成
如果你想得到指定长度的所有排列,可以传递一个可选的长度参数

itertools.combinations() 可得到输入集合中元素的所有的组合

 itertools.combinations_with_replacement() 允许同一个元素被选择多次


enumerate()函数

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

enumerate(sequence, [start=0])
  • sequence -- 一个序列、迭代器或其他支持迭代对象。
  • start -- 下标起始位置。
In [12]: seasons = ['Spring', 'Summer', 'Fall', 'Winter']

In [13]: list(enumerate(seasons))
Out[13]: [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]

In [14]: list(enumerate(seasons, start=1))
Out[14]: [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

zip() 函数

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。其返回的是一个迭代器对象。

我们可以使用 list() 转换来输出列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

In [15]: a=[1,2,3]

In [16]: b=[4,5,6]

In [17]: c=[4,5,6,7,8]

In [18]: zip(a,b)
Out[18]: <zip at 0x16e01abcbc8>

In [19]: for x,y in zip(a,b):
    ...:     print(x,y)
    ...:
1 4
2 5
3 6

In [20]: for x,y in zip(a,c):
    ...:     print(x,y)
    ...:
1 4
2 5
3 6

itertools.zip_longest() 函数可以实现返回列表长度与最长的对象相同,缺失部分可指定填充值

In [21]: from itertools import zip_longest

In [22]: for i in zip_longest(a,c):
    ...:     print(i)
    ...:
(1, 4)
(2, 5)
(3, 6)
(None, 7)
(None, 8)

In [24]: for i in zip_longest(a, c, fillvalue=0):
    ...:     print(i)
    ...:
(1, 4)
(2, 5)
(3, 6)
(0, 7)
(0, 8)

zip() 可以接受多于两个的序列的参数

利用zip()函数可以方便地生成字典

In [25]: s= dict(zip(a,b))

In [26]: s
Out[26]: {1: 4, 2: 5, 3: 6}

itertools.chain() 函数

chain() 函数可以把一组迭代对象串联起来,形成一个更大的迭代器

In [28]: for c in itertools.chain('ABC', 'XYZ'):
    ...:     print(c)
    ...:
A
B
C
X
Y
Z

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值