python-列表生成式、生成器、迭代器

 

列表生成式

现在有个需求,[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
要求你把列表里的每个值加1,你怎么实现?
# 2B青年版
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = []
for i in a:
    b.append(i+1)
print(b)
a = b
print('2B', a)

# 普通青年版
a = [1, 3, 4, 6, 7, 7, 8, 9, 11]
for index, i in enumerate(a):
    a[index] += 1
print('普通', a)
#装B青年版
a = [i+1 for i in range(10)]
print('装B', a)

生成器

  现有一个需求:如果创建一个100万个元素的列表,不仅占用很大内存空间,如果我们只用前面几个元素,那么后面绝大多数元素占的空间都白白浪费了。

1.Python 中,这种一边循环一边计算的机制,称为生成器:generator

2.Python 中,创建一个列表生成器:只需要吧列表生成式的[]改成()

a = [i+1 for i in range(10)]   # 列表生式
print(a)  # 打印列表的值

g = (x*x for x in range(10))   # 列表生成器
for i in g:
    print(next(g))  # 列表生成器 用next()方法获得

3.生成器非常强大,如果算法复杂,用列表生成式for循环无法实现的时候,还可以用函数来实现。

#函数实现斐波拉契数列
#[1, 1, 2, 3, 5, 8, 13, 21, 34]


def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b  # t = a + b  ——》a = b  ——》b = t
        n = n + 1
    return 'done'


fib(10)
#函数实现列表生成器
def fib2(max):
    n, a, b = 0, 0, 1

    while n < max:
        #print(b)
        yield b
        a, b = b, a+b

        n += 1

    return 'done'


data = fib2(10)
print(data.__next__())
print(data.__next__())
print("做别的事")
print(data.__next__())
print(data.__next__())

4.要怎样理解generator的执行流程?

  函数:按顺序执行,遇到return语句货最后一行函数语句就返回。

       生成器:每次调用next()的时候执行,遇到yield语句返回,再次被next()调用时,从上次返回的yield语句处继续执行。

5.上面用next()调用生成器太low,一般用循环+捕获错误来获得返回值。

#用for 循环调用生成器——发现拿不到返回值。
for n in fib2(6):
    print(n)
#如果想要拿到返回值,
# 必须捕获StopIteration错误,
# 返回值包含在StopIteration的value中:
g = fib2(6)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:',e.value)
        break

迭代器:

  1.直接可以作用于for循环的数据类型有以下几种:

    一类:集合数据类型 ——list、tuple、dict、set、str等;

    一类:generator,包括生成器和带yield的generator 函数

   2.可直接作用于for循环的对象称可迭代对象:Iterable.

  3.可以用isintance()判断一个对象是否是可迭代对象:

from collections import Iterable
print(isinstance([], Iterable))       # 列表
print(isinstance({}, Iterable))       # 字典
print(isinstance('abc', Iterable))    # 字符串
print(isinstance((x for x in range(10)), Iterable))  # 生成器
print(isinstance(100, Iterable))    # 数字

   4.可以被next()调用,并不断返回下一个对象称迭代器:iterator

from collections import Iterator
#判断对象是否为迭代器
print(isinstance([], Iterator))       # 列表
print(isinstance({}, Iterator))       # 字典
print(isinstance('abc', Iterator))    # 字符串
print(isinstance((x for x in range(10)), Iterator))  # 生成器

说明:列表、字典、字符串这些都不能被next()返回,所以不是迭代器。

     生成器,带函数生成器可以被next()返回,所以是迭代器。

5.通过iter()函数函数,可以把可迭代对象变成迭代器

#通过iter()函数把可迭代对象转成迭代器
print(isinstance(iter([]), Iterator))

 小结:

1.凡是可以for循环的对象都是——Iterable (可迭代类型)

2.凡是也可以用于next()的对象都是——iterator(迭代器类型),他们代表一个惰性计算的序列(你调用我,我才生成);

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

posted @ 2018-03-24 20:06  OYxing  阅读(315)  评论(0编辑  收藏  举报