Python 入门基础11 --函数基础4 迭代器、生成器、枚举类型

今日目录:

  • 1.迭代器
  • 2.可迭代对象
  • 3.迭代器对象
  • 4.for循环迭代器
  • 5.生成器
  • 6.枚举对象

一、迭代器:

循环反馈的容器(集合类型)
每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值

l = [1, 2, 3]
count = 0
while count<len(l):
    print(l[count])
    count += 1

1.1 为什么要有迭代器?
字符串、列表、元组可以通过索引的方式迭代取出其中包含的元素
字典、集合、文件等类型,没有索引,只有通过不依赖索引的迭代方式才能取值,即迭代器

二、可迭代对象

2.1 什么是可迭代对象
可迭代对象指的是内置有__iter__()方法的对象,即obj.__iter__()

str,list,tuple,dict,set,range(),file,迭代器对象,enumerate(),生成器都是可迭代对象,即:
[].__iter__()
{}.__iter__()
().__iter__()
{1,2}.__iter__()
   ......

三、迭代器对象

3.1 什么是迭代器对象
可迭代对象通过调用__iter__()方法得到迭代器对象
迭代器对象可以不依赖索引取值(一次从容器中取出一个值)
迭代器对象都有__next__方法,且通过该方法获取容器中的值,获取规则,从前往后一次一个
3.2 有哪些迭代器对象
文件类型、enumerate()、生成器是迭代器对象
open(‘a.txt‘).__iter__()
open(‘a.txt‘).__next__()
ps:
    1.迭代器对象去一个值就少一个值
    2.取完了再取会报错  --> 可通过try对异常进行捕获,并处理
    3.上一个迭代器对象迭代取值完毕后,就取空了,如果要再取值,要重新生成迭代器对象
    4.迭代器对象不能求长度(内部值的个数)
    5.迭代器对象一定是可迭代对象,而可迭代对象不一定时迭代器对象

# 迭代器对象
iter_obj = st1.__iter__()
print(iter_obj)  # <set_iterator object at 0x0000025B85231CF0>

print([1, 2, 3].__iter__())  # <list_iterator object at 0x0000017694B0B860>

# 迭代器对象去一个值就少一个值
print(iter_obj.__next__())  # 9
print(iter_obj.__next__())  # 2
print(iter_obj.__next__())  # 3
print(iter_obj.__next__())  # 4
print(iter_obj.__next__())  # 7
# print(iter_obj.__next__())  # 7  # 异常 StopIteration

# 迭代器无法求长度(内部值的个数)
while True:
    try:
        val = iter_obj2.__next__()
        print(val)
    except StopIteration:
        break

四、for 循环迭代器

自带异常处理的while循环,自动获取被迭代的对象的迭代器对象
原理:
    1.执行in后面对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
    2.执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
    3.重复过程2,直到捕捉到异常,StopIteration,结束循环
迭代器的优缺点:
    1.优点
        提过一种统一的、不依赖于索引的迭代方式
        惰性计算,节省内存
    2.缺点
        无法获取长度(只有在next完毕才知道到底有几个值)
        一次性的,只能往后走,不能往前退

# for 循环迭代器,自带异常处理的while循环,自动获取被迭代的对象的迭代器对象
iter_obj = st1.__iter__()
for item in iter_obj:
    print(item)
print(‘----------------华丽的分割线-----------------------------------------------‘)

for item1 in st1:
    # 自动完成for item in st1.__iter__()
    # 自动完成异常处理
    print(item1)

五、生成器

包含yield关键字的函数就是生成器
def fn():
    yield ‘good‘

该函数名()得到的是生成器对象,且不会执行函数体

生成器的应用案例
当访问的数据资源过大,可以将数据用生成器处理,一次只获取所有内容的一条资源

def g_fn():
    print("!!!!!!!!!!!!!!!!!!!!")
    yield ‘第一个‘

    print(‘@@@@@@@@@@@@@@@@@@@@@‘)
    yield ‘第二个‘

    print(‘#####################‘)
    yield ‘第三个‘

    print(‘$$$$$$$$$$$$$$$$$$$$$‘)
    yield ‘第四个‘

g_obj = g_fn()

# 在函数内部执行一次,在遇到下一个yield时停止,且可以拿到yield的返回值
r1 = g_obj.__next__()
print(r1)

# 从上一次停止的地方继续往下走,再遇到下一个yield的时候停止,且可以拿到yield的返回值
r2 = g_obj.__next__()
print(r2)

r3 = g_obj.__next__()
print(r3)

# 重新定义一个range()生成器

def my_range(min, max, step=1):
    # min, max = max, min
    tag = min
    while True:
        if tag >= max:
            break
        yield tag
        tag += step

range_obj = my_range(5, 10, 1)

for i in range_obj:
    print(i)

六、枚举对象

通过for循环迭代器循环遍历可迭代对象,需要知道迭代的索引

作业:

# 1.用生成器完成自定义range方法,可以完成系统range的所有功能

def my_range(min, max= 0, step=1):

    if step > 0:  # 步长为正的
        if max == 0:  # 如果最大值为 0 --> my_range(10)
            min, max = max, min
        tag = min
        while True:
            if tag >= max:
                break
            yield tag
            tag += step

    elif step < 0:  # 步长为负的
        tag = min
        if min > max:
            while True:
                if tag <= max:
                    break
                yield tag
                tag += step

    else:   # 第三个参数不能是 0
        print("第三个参数不能是 0 !")

range_obj1 = my_range(10, 1, -2)
range_obj2 = my_range(10)  # --------可以用
range_obj3 = my_range(2, 10)  # -----可以用
range_obj4 = my_range(2, 10, 2)  # --可以用

"""
for i in range_obj1:
    print(i)
"""

# 2.用生成器完成自定义enumerate方法,也可以为可迭代对象提供索引支持

# ls = [4, 3, 7, 5, 9]
ls = {1,2,3,4,5,6}

def my_enumerate(data):
    count = 0
    for i in data:
        yield (count, i)
        count += 1

"""
for i, v in my_enumerate(ls):
    print(i, v)
"""

# 3.用生成器完成获取阶乘得方法,第一次next得到1的阶乘,第二次next得到2的阶乘,依次类推,

# 直接for循环,可以依次得到指定范围内得所有阶乘,eg:factorial(10),可以得到1~10之间的10个阶乘

def my_factorial(num):
    tag = 1
    for i in my_range(1, num+1):
        tag *= i
        yield tag

factorial_obj = my_factorial(10)

for i in factorial_obj:

    print(i)
"""
1
2
6
24
120
720
5040
40320
362880
3628800
"""

原文地址:https://www.cnblogs.com/xt12321/p/10651229.html

时间: 2024-10-06 17:11:38

Python 入门基础11 --函数基础4 迭代器、生成器、枚举类型的相关文章

python入门(11)条件判断和循环

python入门(11)条件判断和循环 条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= 18: print 'your age is', age print 'adult' 根据Python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做. 也可以给if添加一个else语句,意思是,如果if判断是False,

Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 先定义一个基本的装饰器: ########## 基本装饰器 ########## def orter(func):    #定义装饰器     de

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma

Python入门学习-DAY09-函数基础与参数

函数基础 一 定义函数的三种形式 1.1 无参函数 def foo(): print('from foo') foo() 1.2 有参函数 def bar(x,y): print(x,y) bar(1,2) 1.3 空函数 def func(): pass def upload(): pass def download(): pass def login(): pass def register(): pass def ls(): pass 二 调用函数的三种形式 2.1 语句形式 def fo

Python 入门学习 -----变量及基础类型p一天

Python的变量和数据类型 1 .python的变量是不需要事先定义数据类型的,可以动态的改变 2. Python当中一切皆对象,变量也是一个对象,有自己的属性和方法 我们可以通过 来查看变量的类型:变量名.__class__ 调用变量的方法:变量名.方法() #!/bin/env python #coding:utf-8 #type 打印出数据的类型 print type(1) print type(1.0) print type("helloworld") #虚数 如12j a

Python入门篇(八)之迭代器和生成器

迭代器和生成器 1.列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式.举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)): >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循环: >

python入门系列:函数

引言 将一段代码集中到一块,起一个名字,下次可以根据这个名字再次使用这个代码块.作用:方便代码重用分解任务,简化程序逻辑使代码更加模块化函数的参数 所有的传参方式都是传引用,注意列表做参数和数值做参数容易出现的问题. 单个参数 多个参数 定义方式 def funName(arg1, arg2, arg3...):pass 调用方法 funName(arg1, arg2, arg3...) # 形参和实参一一对应funName(arg2=v2, arg3=v3, arg1=v1) # 指明形参的名

python入门五(函数)【5-2 python中递归函数】

5-2 python中递归函数 Python之递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可以看出: 1 fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n 所以,fact(n)可以表示为 n * fact(n-1),只有n=1时需要特殊处理. 于是,

python基础11 ---函数模块1

函数模块 一.函数模块的作用(为什么要有函数模块) 1.函数模块可以减少代码量 2.函数模块方便阅读 3.函数模块维护性强二.函数模块的本质以及调用方法 1.函数模块的本质就是一个.py结尾的文件,该文件内写入大量函数 2.必须用import来引用函数模块,在调用函数模块时必须以"模块名.函数名"来调用函数模块中的函数. 3.有的时候我们只需要用到模块中的某个函数,也可以用"from 模块名 improt 函数1,函数2"的方式来引用该模块,但只是一次引用,不建议使