python-迭代器和生成器

50次阅读

共计 2976 个字符,预计需要花费 8 分钟才能阅读完成。

二者区别

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)

in

—-> 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__() 方法来实现反向迭代

迭代器切片
外汇返佣 http://www.fx61.com/

函数 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]:

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