python迭代器、生成器、三元表达式、列表、字典解析式、生成器表达式

迭代器

1.什么是迭代器:

    迭代器简单来讲就是迭代取值的工具

    迭代是一个重复的过程,每一次重复都是基于上一次的结果而来,单纯的重复并不是迭代。

while True:

    print('x')   #这种单纯的循环不是迭代

我们尝试用while循环实现迭代过程:

l = ['a', 'b', 'c']

def iterator(item)

    i = 0

    while i < len(item):

        print(l[i])

        i += 1

iterator(l)

2.为什么要有迭代器?

    基于索引取值的数据类型只适用于列表、元组、字符串类型

    那么对于没有索引的字典、集合、文件等,则不适用

    所以需要找到一种通用的并且不依赖索引的迭代取值方式---> 迭代器

    至此,假设我们从来不知道for循环是什么东西。

那我们如何使用现有的知识模拟迭代的过程呢

s = 'hello'

def iterator(item):

    i = 0

    while i < len(item):

        print(item[i])

        i += 1

iterator(s)

我们先简单了解下几个概念:

    可迭代对象:先简单解释为在python中但凡内置有__iter__方法的对象都是可迭代对象,字符串、元组、列表、字典、集合、文件都是可迭代对象,即上述类型的数据都内置有___iter___方法使用

    迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象

    执行可迭代对象的__iter__方法得到的就是内置的迭代器对象

    文件对象本身就是迭代器对象

    迭代器对象一定是可迭代对象,反之则不然

我们看个简单的例子加深以上概念的印象:

info = {'name': 'zhangsan', 'age':24}

info__iter = info.__iter__()  #这一行是由内置__iter__方法从可迭代对象中取出迭代器对象

print(info_iter)

res1 = info__iter.__next__() #假设我们不知道循环,继续取值

print(res1)

res2 = info__iter.__next__() 

print(res2)

res3 = info__iter.__next__() #一旦迭代器将可迭代对象取值完毕,再继续取值就会跑出StopIteration的异常


我们假设已经学习了异常处理的知识,改进如下:

info = [1, 2, 3, 4]

info__iter = info.__iter__()

while True:

    try:

        print(info__iter.__next())

    except StopIteration:

        break

现在来介绍下for循环,for循环也叫迭代器循环

for循环的对象一定要是可迭代对象

info = {'name':'zhangsan', 'age': 21, 'sex':'male'}

for i in info:  #其实等同于info__iter = info.__iter__() 

    print(i)

f = open('a.txt', 'r')

for k in f:

    print(k)

我们再来说一下什么是迭代器对象呢?

    迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象。

这里我们还要注意:执行迭代器对象的__next__得到的是迭代器的下一个值;执行迭代器对象的__iter__得到的仍然是迭代器本身。

info = [1, 2, 2, 3,]

iter__info = info.__iter__()

print(iter__info)

print(iter__info is iter__info.__iter__() is iter__info.__iter__().__iter__().__iter__().__iter__()) #迭代器对象的__iter__得到的仍然是迭代器本身

总结迭代器对象的优缺点:

优点:

    提供了一种通用的、可以不依赖索引的迭代取值方式

    迭代器对象更加节省内存

缺点:

    迭代器的取值不如按照索引取值的方式灵活,因为它只能往后取,不能往前退。

    无法预测迭代器值的个数。

  • 生成器

什么是生成器:在函数内凡是出现yield 关键字,再掉用该函数就不会执行函数体代码,会返回一个值,该值就被称为生成器。

生成器是一种自定义的迭代器

下面我们看看如何使用

def func():

    print('first')

    yield 1

    print('second')

    yield 2

    print('third')

    yield 3

g = func()  #g是一个迭代器

res1 = next(g) # 用内置方法next执行一次迭代器对象

print(res1)

res2 = next(g) 

print(res2)

我们尝试着自己造一个range函数出来:

def my_range(start, stop, step = 1):

    while start < stop:

        yield start #将函数暂停

        start += step

g = my_range(1, 9, 2)

for i in g:

    print(i)

总结下yield的功能:提供一种自定义迭代器的方式;yield可以暂停住函数,并返回值。

与return的相同点是:都用在函数内,可以有返回值,无类型和个数限制

不同点是:return只能返回一个值,yield能返回多次值

  • 三元表达式

python中三元表达式格式如下:

为真时结果 if 判定条件 else 为假时结果

1 if 10>3 else 0

结果为1

  • 列表解析式

根据现有的列表高效的创建新列表,是迭代机制的一种应用,具体应用如下:

l = [i  for i in range(1,11)]

我们可以很快造出一个从1到10的列表。

l1 = ['a', 'b', 'c', 'd', ]

l1 = [k.upper() for k in l1] #将l1中的元素改为大写

l2 = [i ** 2 for i in range(10) if i > 5] #造一个1到9的列表,其中大于5的元素全部取平方

  • 字典解析式

与列表解析式相似,要注意的是字典是以键值对存取数据

现在有两个列表,通过zip函数可以将列表的元素对应存储起来,然后用字典解析存储成键值对,如下:

keys -=['name', 'age', 'sex']

values = ['zhangsan', 25, 'male']

dic = {k:v for k, v in zip(keys, values)}

print(dic)

生成器表达式

g = (i for i in range(10))

print(g)

print(next(g))

print(next(g))#自定义生成器

打印某个文件中字符数最多的一行:

with open('a.txt', encoding = 'utf-8')as f:

    nums = (len(line) for line in f)

    print(max(nums))

print(max(nums))#试试这两处打印都会有什么结果呢?

猜你喜欢

转载自blog.csdn.net/zhou_le/article/details/80666749