【Python】列表生成式、生成器、迭代器

列表生成式

常见的列表生成方式:
1.list

>>> list(range(1,5))
> [1,2,3,4]

2.for循环

l=[]
for i in range(1,5):
    l.append(i)
>>>l
>[1,2,3,4]

3.列表生成式 : 在列表生成时加入限制判断条件
例:

#[1,2,3,4]
[x for x in range(1,5)]

可以添加限制条件

#[2.4]
[x for x in range(1,5) if x%2==0]

用于求全排列

#['AY','AZ','BY','BZ']
[a+b for a in 'AB' for b in 'YZ']

但是三层或三层以上的循环在实际中很少用到。

读取文件名

>>> import os 
>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录
['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']

for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value。

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

生成器

“列表生成式”式生成器

创建生成器的其中一种方法,就是将列表生成式的 [ ] 换成 ( )
例:

>>> g = (x*x for x in range(1,5))
> g
> <generator object <genexpr> at 0x02AE8D48>

与列表生成式不同的是,这样创建出的生成器不会打印出g中每一个元素,而是如上所示。这是因为,生成器所保存的是一种算法,而不是某些具体的元素。
要打印出g中的每一个元素,需要使用next()方法:

>>> next(g)
> 1
>>> next(g)
> 4
>>> next(g)
> 9
>>> next(g)
> 16
>>> next(g)
>Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
 StopIteration

当计算到最后一个元素后,没有更多的元素,计算机会抛出StopIteration错误
当然,也可以用for循环来直接输出,可以将g能生成的所有元素打印出来。但是不会有StopIteration

for i in g:
    print(i)

函数式生成器 yield
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(n):
    x,a,b = 0,0,1
    while x<n:
    	print(b)
    	a,b = b,a+b
    	x += 1
    return 'done'

仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
要把fib()函数变成generator,只需要将print(b)转换成yield b即可。

这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

def fib(n):
    x,a,b = 0,0,1
    while x<n:
    	yield b
    	a,b = b,a+b
    	x += 1
    return 'done'

generator和函数的执行流程不一样。函数顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

>>> for fib_num in fib(6):
...     print(fib_num)
...
>1
>1
>2
>3
>5
>8

但是却提取不到return返回值 ‘done’。
前面说过,当计算到最后一个元素后,没有更多的元素,计算机会抛出StopIteration错误。
因此,如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中。

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

迭代器

可以直接作用于for循环的对象统称为可迭代对象:Iterable
如:list,tuple,dict,set,str
还有上面提到的generator
可以使用isinstance()判断一个对象是否是Iterable对象.(from collections import Iterable)

可迭代对象却不一定是迭代器(iterator)。可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
符合这一条件的 : generator 不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值。
可以使用isinstance()判断一个对象是否是Iterator对象.(from collections import Iterator)

集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值