迭代器、生成器、模块和包

本文探讨了Python中的基础概念,包括迭代器和生成器的使用,详细阐述了两者的区别与联系。此外,还介绍了模块和包的组织方式,帮助读者理解如何在Python项目中有效地组织和导入代码。通过代码练习和问题解答,加深了对这些概念的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python基础 迭代器和生成器、模块和包
1.迭代器和生成器
1.迭代器
    迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法。
    其中__iter__()方法返回迭代器对象本身;__next__()方法返回容器的下一个元素,在结尾时引发StopIteration异常。
2.生成器generator
    在Python中,使用生成器可以很方便的支持迭代器协议。
    生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和
继续它们的状态,来自动实现迭代协议。
    也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。
    生成器函数返回生成器的迭代器。 “生成器的迭代器”这个术语通常被称作”生成器”。
    要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法。
    其中一个就是__next__()。如同迭代器一样,我们可以使用__next__()函数来获取下一个值。
    在一个 generator function 中,如果没有 return,则默认执行至函数完毕,如果在执行过程中 return。
    则直接抛出 StopIteration 终止迭代。   
2.模块和包
1.内置模块
    本身就带有的库,就叫做Python的内置的库。(模块==库)
    一些常见的内置模块
    os 和操作系统相关   os.path
    sys 和系统相关     sys.path  
        sys.path.append(r'')    可以添加路径
    re  正则表达式 

2.第三方模块
    非Python本身自带的库,就是所谓的第三方的库

3.模块的导入
    import xxx  [as  yy]
    from ../xx  import  xx  [as  yy]  

4.自定义模块
    py文件,可以做为一个模块来用,直接作为一个模块导入就行
    __main__ 的意义:
        当文件是直接运行是,文件的__name__是__main__ ,当文件是被
    导入时,__name__是文件名

5.包管理
    基本上就是另外一类模块。把用来处理一类事物的多个文件放在同一文件夹
下组成的模块集。
    要让python 将其作为包对待,在python2中必须包含__init__.py的文
件,但在python3中没有__init__.py文件也可以,使用包可以避免多个文件
重名的情况,不同的包下的文件同名不影响。   
    导入包和模块是一样的方法,包导入后会在目录中自动生成__pycache__文
件夹存放生成的.pyc文件,要注意的是import后面的才是存在当前作用域中的对
象名,from是告诉python从什么地方导入,使用sys.path添加文件的目录路径。
代码练习:
##列表推导式
li=[]
for i in range(21):
     if i%2==0:
          li.append(i)
print(li)
for i in range(0,20,2):
          print(i)
li2=[i for i in range(21) if i%2==0]
print(li2)
li3=['a' for i in range(21) if i%2==0]
print(li3)
li4=[]
for i in range(21):
     if i%2==0:
          li4.append(i)
     else:
          li4.append('a')
print(li4)
li4=[i if i%2==0 else 'a' for i in range(21)]
print(li4)
##
se={i for i in range(10)}
print(se)
di={i:'a' for i in range(10)}
print(di)
##迭代器
##enumerate([1,2,3])#返回一个枚举对象,同时也是迭代器
##next()##迭代器可用操作
print(li.__iter__())   #用这个方法变成迭代器
g=li.__iter__()
print(g)
print(g.__next__())   #实现迭代器,就是取值

print(iter(li))#列表转化为一个迭代器对象并返回
h=iter(li)
print(h)
print(h.__next__())#等同于next(h)

###必须赋值给变量接受
g=iter(li)
print(g)
for i in g:
    print(i)

##生成器     本质上是迭代器
def fun():
     i=1
     while i <5:
          print(i)
          yield 'stop'  #实现生成器的功能  暂停 返回值
          i+=1
          print('**1234',i)
fun()
##斐波拉契 1,1,2,3,5,8,13,21,34
def fib(num):
     n=0
     a,b=0,1
     while n<num:
          print(b)
          if n%10==0:
               yield
          a,b=b,a+b
          n+=1
g = fib(31)
print('--------')
next(g)
print('--------')
next(g)
print('--------')
next(g)
print('--------')
print('--------')
next(g)
print('--------')
#递归:斐波拉契 1,1,2,3,5,8,13,21,34
def fib(n):
    if n<=1:
        return n
    else:
        return(fib(n-1)+fib(n-2))
print('递归实现:',fib(10))
##模块和包
#模块:自带模块  第三方模块
#导入所有内容 很直观 占内存
##import random
##random.randint()
# 指定导入  
##from copy import deepcopy
##deepcopy()
#python 
#Lib为python库安装目录
##  pip 安装python第三方包命令:pip install xlwt,xlrd
##  pip 卸载python第三方包命令:pip uninstall xlwt,xlrd
##模块 即py文件
##包 即很多py文件放在一个文件夹里,形成包
##python 模块中含有:
##方法 函数
##属性 变量名

#相同路径(即同目录下)直接导入
#import modular
#不同路径
##第一步:import sys
##sys.path 添加库文件模块,方法实现如下:
##第二步sys.path.append(r'库文件路径')
##第三步:模块函数调用modular.python() 、modular.fib(n).....
####木块实现样例文件名modular.py:
'''
##python  模块

def python():
    print('hello everyone!')
    a='my name is python'
    return a

def fib(n):
    if n<=1:
        return n
    else:
        return(fib(n-1)+fib(n-2))


python='python is very handsome'

if __name__=='__main__':  
    print('main')
    python()
'''
'''这个表示执行的是此代码所在的文件。
如果这个文件是作为模块被其他文件调用,不会执行这里面的代码。
只有执行这个文件时, if 里面的语句才会被执行。
这个功能经常可以用于进行测试。

'''
'''
'''

输出结果:

==========
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
0
2
4
6
8
10
12
14
16
18
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a']
[0, 'a', 2, 'a', 4, 'a', 6, 'a', 8, 'a', 10, 'a', 12, 'a', 14, 'a', 16, 'a', 18, 'a', 20]
[0, 'a', 2, 'a', 4, 'a', 6, 'a', 8, 'a', 10, 'a', 12, 'a', 14, 'a', 16, 'a', 18, 'a', 20]
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
{0: 'a', 1: 'a', 2: 'a', 3: 'a', 4: 'a', 5: 'a', 6: 'a', 7: 'a', 8: 'a', 9: 'a'}
<list_iterator object at 0x000000876F621EF0>
<list_iterator object at 0x000000876F62FBA8>
0
<list_iterator object at 0x000000876F8D4AC8>
<list_iterator object at 0x000000876F8D4AC8>
0
<list_iterator object at 0x000000876F8D4A90>
0
2
4
6
8
10
12
14
16
18
20
--------
1
--------
1
2
3
5
8
13
21
34
55
89
--------
144
233
377
610
987
1597
2584
4181
6765
10946
--------
--------
17711
28657
46368
75025
121393
196418
317811
514229
832040
1346269
--------
递归实现: 55
>>> 
问题解答:
# 题1
'''
在这一个月,我们学了python基础,简单总结下,有六种数据类型和函数。
(1)请从str,list,dict,set选出 1 种数据类型,进行归纳总结。
(2)请整理函数的知识点进行归纳总结。

#例  元组(tuple)
#1.可变不可变对象?序列还是非序列?
#2.操作元祖的方法有多少种,其中哪几个方法使用频率高,并选择1-3个方法进行代码展示
#3.是否可迭代
#4.索引和步长简单展示
#5.其他用法
#开放题,想到多少写多少,可以通过回顾视频以及查资料的方法完成此题。
#以元祖为例,完成1.2.3便可拿到此题的及格分。
'''
#解答:
'''
列表(list)
1.列表为可变对象,是序列的一种
2.操作元组有11种,其中使用频率最高的为一下几种:
----->L.insert(index,obj) 插入元素,可以指定位置。
----->L.sort() 对原列表进行排序。列表中的元素要类型相同
----->L.append(obj) 在列表末尾添加新的对象。
----->L.index(obj) 从列表中找某个值第一个匹配项的索引位置。
----->L.pop(index) 出栈,可以指定位置。index默认是L[-1]
----->L.remove(obj) 移除指定元素从左边开始的第一个。
----->L.count(obj) 统计某个元素在列表中出现的次数。
----->L.extend(obj) 用obj扩展原来的列表。
----->L.clear() 清空整个列表。
----->L.copy() 复制列表。
'''
#列表的方法
#定义一个列表
li = [5,4,3,2,1,6,3]
li.insert(3,'li')#元素插入方法,即根据索引位置插入对应元素,本操作索引为3,插入元素为li字符
print(li)
s = li.count(3) #统计元素的个数,即统计元素3在列表中的个数
print(s)
d = li.index(4) #返回对应元素的下标,即返回4在列表的下标位置
print(d)
li=['a','b','c','d']
li.sort(key=None,reverse=True)#对元素进行排序,默认按照ascii码排序
print(li)
li.remove('c')#删指定动元素,即删除列表中的c元素
print(li)
'''
3.列表为可迭代对象
'''
#4.索引和步长简单展示
li = [1,2,3,4,5,6,7,8,9,10]
print(li[2])#直接根据索引获得对应元素
print(li[1:10:2])#根据起始索引以及终止索引加步长获取对应元素序列
print(li[:10:2])#第一个元素默认为索引0,第二个元素默认为列表长,第三个元素为步长
print(li[-1:-10:-2])#步长以及索引可以为负值,即反向获取元素序列
#5其他方法
#内置函数:
#1.sorted()和 reversed()
#2.深浅复制

##2222222
##(2)请整理函数的知识点进行归纳总结。
#111函数的定义
#定义方法:
def function_name(a):
    print(a)
#222函数的参数详解
#1.必备参数:参数没有默认值
#2.默认参数:参数有默认值,调用函数是可以传参也可以不传参,不传参时,参数是默认值
#3.不定长参数: 可在定义时定义,也可在传入时传入
#    定义方法: def function_name(*args,**kwargs):
#    *args 将传入参数包装成元组
#    **kwargs将传入参数包装成字典
#333return的作用
###1用来返回函数的运行结果
###2函数结束的标志
###3return语句的位置是可选的,不是固定出现再函数的最后,可以自定义在函数中的任何地方。
#444lambda匿名函数
####定义:
g = lambda x:x+1  #即没有名字的函数
####lambda的应用:
#1.临时一用、逻辑简单
#2.函数都支持函数作为参数,lambda 函数就可以作为参数
#555内置函数
########
'''
常见的内置函数:
查看内置函数:
        print(dir(__builtins__))
    常见函数
    len 求长度
    min 求最小值
    max 求最大值
    sorted  排序
    reversed 反向
    sum  求和
进制转换函数:
    bin()  转换为二进制
    oct()  转换为八进制
    hex() 转换为十六进制
    ord() 将字符转换成对应的ASCII码值
    chr() 将ASCII码值转换成对应的字符
1.enumerate()   #返回一个可以枚举的对象
2.filter() #过滤器
3.map() #加工
4.zip() #将对象逐一配对

'''
#666函数内变量的作用域
'''
global :函数中,需要修改全局变量时,用global
    nonlocal:当里层局部,需要修改外层局部时,需要使用nonlocal。
'''
#777内嵌函数和闭包
'''
内嵌函数: 在函数内部定义函数,就是函数里面嵌套函数
闭包:一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。
      这个返回的函数B就叫做闭包。
'''
#888递归函数
'''
递归: 函数调用自己本身
'''
##递归   调用自己
def age(n):
     if n==1:
          return 18
     else:
          return age(n-1)+2
age(5)

# 题2
'''
利用列表推导式: 找出100以内所有奇数,并将所有奇数乘以3,写入列表。
'''
#解答:
li = [i*3 for i in range(101) if i%2!=0]
print(li)
# 题3
'''
猴子第一天摘下N个桃子,当时就吃了一半,还不过瘾,就又多吃了一个。第二天又将剩下的桃子吃掉一半,又多吃了一个。
以后每天都吃前一天剩下的一半零一个。
到第10天在想吃的时候就剩一个桃子了,
问第一天共摘下来多少个桃子?
'''
#解答:
print('---------------------')
def monkey(n=10):
    if n==1:
        return 1
    else:
        return (monkey(n-1)+1)*2

print('第一天共摘下来%d个桃子'%monkey())

# 题4
'''
现有一个列表,其中有10个元素,元素均为int类型,列表内的数据是无序。
现在要求我们通过编写一个程序将这列表变成一个从小到大排序的列表
请用自己的代码完成。
'''
li = [10,9,8,3,2,6,4,5,7,1]
def bubbleSort(li):
    lenght = len(li)
    for i in range(0,lenght-1):
        for j in range(0,lenght-i-1):
            if li[j]>li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
    return li
print('#4.解答:')
print(bubbleSort(li))
# 题目5
'''
定义一个函数:
    统计传入的字符串里,英文字母、空格、数字和其他字符分别出现次数,
    并作为一个字典返回   {'字母':  ,'空格':   ,'数字':   ,'其他字符:' }
'''
li ='abcdef      123456678###$******$&%'
def count(li):
    countE =0
    countB =0
    countM =0
    countO =0
    for i in range(len(li)):
        if (li[i]>='0')&(li[i] <='9'):
            countM +=1
        elif (li[i] >='a')&(li[i] <='z')|(li[i] >='A')&(li[i] <='Z'):
            countE +=1
        elif li[i] == ' ':
            countB +=1
        else:
            countO +=1
    print(countE,countB,countM,countO)
    dir = dict()
    dir.update({'字母':countE,'空格':countB,'数字':countM,'其他字符':countO})
    return dir
print(li)
print(count(li))
# 题6
'''
请定义一个名为titles的函数:
    1.接收一句英文(字符串)作为参数
    2.将这个英文的每个单词转换成有且只有首字母大写的形式
    3.返回转换后的英文句
    4.str.title具有这个功能,但在此题不可使用str.title

例如:
>>> titles('this is python.')
'This Is Python.'
>>> titles('i love python')
'I Love Python'

'''
#解答:
li1 = 'this is python.'
li2 ='i love python.'
li3 ='i love python and i like program.'
def titles(li):
    lines = li.split(' ')
    for i in range(0,len(lines)):
        tmp = lines[i][0].upper()
        lines[i] = lines[i].replace(lines[i][0],tmp,1)
    lines = ' '.join(lines)
    lines = lines.replace(',',' ')
    return lines
s = titles(li1)
print(s)
s = titles(li2)
print(s)
s = titles(li3)
print(s)

结果输出:

======
[5, 4, 3, 'li', 2, 1, 6, 3]
2
1
['d', 'c', 'b', 'a']
['d', 'b', 'a']
3
[2, 4, 6, 8, 10]
[1, 3, 5, 7, 9]
[10, 8, 6, 4, 2]
[3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75,
 81, 87, 93, 99, 105, 111, 117, 123, 129, 135, 141,
 207, 213, 219, 225, 231, 237, 243, 249, 255, 261,
  267, 273, 279, 285, 291, 297]
---------------------
第一天共摘下来1534个桃子
#4.解答:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
abcdef      123456678###$******$&%
6 6 9 13
{'字母': 6, '空格': 6, '数字': 9, '其他字符': 13}
This Is Python.
I Love Python.
I Love Python And I Like Program.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泸州月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值