python列表生成式,生成器,迭代器

列表生成式

在Python语言中,所谓的列表生成式,顾名思义,就是说可以生成list列表的表达式,是Python内置的一种强大的功能。列表生成式即List Comprehensions,列表生成式作用是用来生成列表的,那么其特点也肯定是使用“[]”来去表示的。

例如想对列表里面的数据进行运算后重新生成一个新的列表,如[1,2,3 ... 100],按平常思维就是先定义一个列表c,然后for循环挨个运算,算完了再append添加到c,最后c就是新的列表了:

a = range(1,10)
c = []
for i in a:
    c.append(i*i)
print(c)    #[1, 4, 9, 16, 25, 36, 49, 64, 81]

使用函数也是如此:

def f(n):
    return n**2
a = [f(x) for x in range(5,10)]
print(a)        #[25, 36, 49, 64, 81]

生成器

定义:一边循环一边计算的机制,称为生成器(generator);

为什么使用生成器:

通过列表生成式,我们可以直接创建一个列表,列表所有的数据都在内存中,所以大量的数据会非常消耗内存,而生成器一次产生一个值,这样消耗的内存数量将会大大减小,所以想要得到大量的数据,又想占用内存少,就使用生成器(所有的生成器都是一个迭代器)。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

创建一个生成器:只要把一个列表生成式的[]改成(),就创建了一个generator:

s = [x * 2 for x in range(1,10)]
print(s)    #[2, 4, 6, 8, 10, 12, 14, 16, 18]

a = (x * 2 for x in range(1,10))
print(a)    #<generator object <genexpr> at 0x02C2FF70>

通过next()方法打印generator的每一个元素:

a = (x * 2 for x in range(1,10))
print(a)    #<generator object <genexpr> at 0x02C2FF70>
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))

输出结果:

<generator object <genexpr> at 0x031AFF70>
2
4
6
8
10
12
14
16
18

不断调用next()方法效率太差,正确的使用方法是使用for循环;

a = (x * 2 for x in range(1,10))
for i in a:
    print(i)
2
4
6
8
10
12
14
16
18

使用函数打印斐波拉契数列,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

def fib(max):
    n , b , a = 0 , 0 , 1
    while n < max:
        print(a)
        b , a = a , b + a
        n += 1
fib(10)
1
1
2
3
5
8
13
21
34
55

要把fib函数变成generator,只需要把print b改为yield b就可以了:

def fib(max):
    n , b , a = 0 , 0 , 1
    while n < max:
        yield(a)
        #print(a)
        b , a = a , b + a
        n += 1
g = fib(10)
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
<generator object fib at 0x0053FF70>
1
1
2
3
5
8
13

迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式;

迭代器是一个可以记住遍历的位置的对象;

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退;

迭代器有两个基本的方法:iter() 和 next();

字符串,列表或元组对象都可用于创建迭代器;

例如:

l = [1,2,3,4,5]
d = iter(l)
print(d)
print(next(d))
print(next(d))
print(next(d))
print(next(d))
<list_iterator object at 0x02F2DDF0>
1
2
3
4

迭代器对象也可以使用for循环进行遍历:

l = [1,2,3,4,5]
d = iter(l)
print(d)
for i in d:
    print(i,end=" ")
<list_iterator object at 0x02B0DE50>
1 2 3 4 5 

for循环内部三件事:

1、调用课程迭代对象iter方法,返回一个迭代器对象;

2、不断调用迭代器对象的next方法;

3、处理StopIteration;

小结:

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

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

 

参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值