python基础学习(迭代器,生成器,模块,包)

############################################1.迭代器(iterator)
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问结束为止,迭代器只能往前不会后退。

迭代是一个怎样的过程 ?
就是一个依次从数据结构中拿出东西的过程

(1)# 列表推导式:能够简洁的构造一个新列表

#一般情况写这样构造一个新列表
li = []
for i in range(1,10):
li.append(i)
print(li) # 输出为:[1, 2, 3, 4, 5, 6, 7, 8, 9]

#列表推导式
li1 = [i for i in range(1,10)]
print(li1) # 输出为:[1, 2, 3, 4, 5, 6, 7, 8, 9]

#升级篇 做出1-9之间的偶数 (当然也可以使用range(1,10,2)
li3 = [i for i in range(1,10) if i % 2 !=0]
print(li3) # 输出为:[1, 3, 5, 7, 9]

#又升一级 如何打印出多个值呢
li4 = [(i,j) for i in range(1,5) for j in range(1,5)]
print(li4) # 输出为: [(1, 1), (1, 2), (1, 3), (1, 4),
# (2, 1), (2, 2), (2, 3), (2, 4),
# (3, 1), (3, 2), (3, 3), (3, 4),
# (4, 1), (4, 2), (4, 3), (4, 4)]
(2)# 集合推导式
li5 = {i for i in range(1,10)}
print(li5) # 输出为:{1, 2, 3, 4, 5, 6, 7, 8, 9}

(3)# 字典推导式
li6 = {i:j for i in range(1,10) for j in range(1,10)}
print(li6) # 输出为:{1: 9, 2: 9, 3: 9, 4: 9, 5: 9, 6: 9, 7: 9, 8: 9, 9: 9}

#小拓展:
li7 = {i:j for i,j in enumerate([‘吴某’,‘张某’])}
print(li7) # 输出为:{0: ‘吴某’, 1: ‘张某’}

注意:是没有元组推导式的!!!

小知识点:
(1)迭代
for 迭代变量 in 可迭代对象
#每一次循环都会自动让“迭代变量”指向“下一个元素”。
(2)可迭代对象指:
可迭代对象(实现了__iter__这个方法的都是):序列类型和散列类型
(3)迭代器指:
迭代器(实现了__iter__和__next__方法的就是,迭代器是一个对象) 只能前进不能后退。
(4)从可迭代对象生成一个迭代器
迭代器 = iter(可迭代对象)
下个值 = next(迭代器)

来个例子:
#列表是一个可迭代对象,dir查看列表方法的时候里面有__iter__方法,
#但列表不是一个迭代器,如何把列表转换为一个迭代器
li = [1,2,3,4]
it = iter(li)
########获取迭代器的值
for i in it:
print(i) #这样会取到所有的值
########既然是迭代器了,就通过next方法去获取迭代器的值
#这样一次只取一个值,可以省内存空间。
#next两种使用方式
print(it.next()) # 输出为:1
print(next(it)) # 输出为:2

小拓展:::
#for 实现原理
li = [1,2,3,4]
it = iter(li)
try:
while True:
print(next(it))
except Exception as e:
print(e)
输出为:
1
2
3
4

##############################################2.生成器(generator)
思考一: 我们如何自己实现一个可迭代对象 ?
在自定义的类中,要实现 iter 魔术方法
该魔术方法,必须要返回一个 迭代器
(也需要自己实现)
思考二: 是否有更加有更加优雅的方式 ?
生成器

#生成器:返回迭代器的函数
#1.元组推导式
tu = (i for i in range(1,10))
print(type(tu)) # 输出为:<class ‘generator’> 意思是这是个生成器
print(dir(tu)) # 可知tu里面有方法__iter__和__next__,所以这是个迭代器
print(tu.next()) # 既然是一个迭代器,就可以使用next方法取值

#2.yield 凡是有yield的函数都是生成器
| 返回这个对象
yield 一个对象| 暂停这个函数
| 等待下次next重新激活

来个例子:
def fun(): # 定义生成器,由next函数触发执行
print(‘好好学习’)
yield 1 #返回一个1 并暂停函数
print(‘天天向上’)
yield 2 #返回一个2 并暂停函数
print(‘再来一次’)
#没有代码了,引发StopIteration异常

a = fun()
aa = next(a) # 输出为: 好好学习
print(aa)) # 输出为: 1
bb = next(a) # 输出为: 天天向上
print(bb) # 输出为: 2
cc = next(a) # 输出为: 再来一次 并抛出StopIteration异常
#如果print(type(fun())),会输出<class ‘generator’>,可见这个函数已经是一个生成器了。

再来个例子看看:
def fun(ele,n):
count = 0
while True:
if count < n:
count +=1
yield ele
else:
break

a = fun(‘wumou’,5)
for i in a:
print(i)
输出为:
wumou
wumou
wumou
wumou
wumou

迭代器生成器的总结:
生成器 与 迭代器 的区别:
生成器,是Python提供的一种非常简便的语法能让我们来自己写出迭代器
注意! 生成器,是一种特殊的迭代器
生成器指的是一个函数,返回的结果是一个迭代器
而迭代器是一个对象

#########################################3.导入模块:
总共有这几种导入的方式:::
from car import Car #从一个只包含一个类的模块中导入这个类

from car import ElectricCar #从一个包含多个类的模块中导入一个类

from car import Car, ElectricCar #从一个有多个类的模块中导入多个类

import car #导入整个模块 我们使用语法 module_name.class_name 访问需要的类

from module_name import * #导入模块中的所有类 (不建议使用,如果要用,推荐使用导入整个模块)

例子:
第一种:
import datetime # 导入整个datetime模块
a = datetime.datetime.now() # 获取当前时间
#第一个datetime是模块,第二个datetime是模块里面的类,,now()是类里面的方法
第二种:
(1)
from datetime import datetime #导入模块里面的一个类
a = datetime.now() #直接就一个datetime就是模块里的类
(2)
from datetime import * #导入这个模块里的所有类
a = datetime.now() #直接就一个datetime就是模块里的类
第三种:
from datetime import datetime as y #取别名
a = y.now()

升级高级的:
sys.path 用于存放导入路径的列表,类似于环境变量中的 PATH
sys.argv 查看当前文件路径
pycache: 缓存文件

例子:
import sys
print(sys.path) #在这个路径下面,就可以通过import直接导入。一个列表,在前面的路径优先级高。
#只有在这个列表里面的路径的才能被导入。

第一个问题:
#如果自己写的一个文件和python自带的一个模块重名,而且自己写的这个文件在本目录下,
#那么如果直接导入这个模块,本目录下的优先级最高,就导入不了自带的那个模块。
#解决方法: sys.path.insert(0,路径名),把想要导入的那个模块的路径改到列表的前面。

第二个问题:
#如果需要导入的模块在别的盘,即不在这个路径列表里,该怎么导入:
sys.path.append(r’路径名’)

发布了14 篇原创文章 · 获赞 15 · 访问量 224

猜你喜欢

转载自blog.csdn.net/qq_44907926/article/details/104342986
今日推荐