Day5笔记

一、可迭代对象和迭代器【掌握】

【面试题:简述可迭代对象和迭代器之间的区别和联系】

1.可迭代对象

可以直接作用于for循环的对象统称为可迭代对象【Iterable】

判断方式:isinstance():可以判断一个对象是否是可迭代对象

可迭代对象有:

​ a.一类是集合类型,比如:list,tuple,dict,set,string等

​ b.一类是生成器【generator】,包括()和yield的function generator

from  collections import  Iterable

#isinstance(数据,类型)
#print(isinstance(10,int))

print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({},Iterable))
print(isinstance((i for i in range(10)),Iterable))
print(isinstance("",Iterable))

print(isinstance(10,Iterable))
print(isinstance(True,Iterable))
2.迭代器

不但可以直接作用于for循环,还可以被next函数不断调用返回下一个值,直到最后一个元素获取到

问题:如果通过next将生成器中的元素遍历完成,继续调用next,会出现一个StopIteartion的异常

可以被next调用并返回下一个元素的对象被通称为迭代器【Iterator】

判断方式:isinstance():可以判断一个对象是否是迭代器

from  collections import  Iterator



print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({},Iterator))
print(isinstance("",Iterator))
print(isinstance((i for i in range(10)),Iterator))

#正常情况下,只有生成器才是迭代器
#联系:迭代器一定是可迭代对象,可迭代对象不一定是迭代器

print("++++++++++")

#iter()可以将list,tuple等转换为迭代器
print(isinstance(iter([]),Iterator))
print(isinstance(iter(()),Iterator))
print(isinstance({},Iterator))
print(isinstance("",Iterator))


#for循环的工作原理:通过不断调用next函数实现的
list1 = [22,33,44,55,66,77]

#for
# for num in list1:
#     print(num)

#完全等价于:next
it = iter(list1)
# num1 = next(it)
# print(num1)
# num1 = next(it)
# print(num1)
# num1 = next(it)
# print(num1)

while True:
    try:
        #监控区
        x = next(it)
        print(x)
    except StopIteration:
        #一旦进入except代码块,则说明迭代器中的元素已经遍历完成,则退出循环
        break

二、列表生成式和生成器【掌握】

1.列表生成式

列表生成式:List Comprehesions,是Python内置的专门用来生成列表的工具

语法:[元素的规律 for循环 if判断]

#1.需求:生成一个列表[1,2,3,4,5,6,7,8,9]
list1 = list(range(1,10,1))
print(list1)

#2.需求:生成一个列表[1,4,9,16,25...]
#range的弊端:生成的可迭代对象都具有一定的规律,相当于是数学上的等差数列
#自定义功能
newList1 = []
for i in range(1,10):
    newList1.append(i ** 2)
print(newList1)
#列表生成式
list3 = [x ** 2 for x in range(1,10)]
print(list3)
print(type(list3))

#3.需求:生成一个列表[4,16,36,64.....]
#列表生成式的顺序:for---->if判断----》元素的规律
list4 = [x ** 2 for x in range(1,10) if x % 2 == 0]
print(list4)
#等价于
newList2 = []
for i in range(1,10):
    if i % 2 == 0:
        newList2.append(i ** 2)
print(newList2)

#4.需求:使用双层循环,实现全排列
#排列:从m个元素中取出n个元素【n <= m】,按照一定的顺序进行排列,得到的结果成为排列,如果当m == n的时候,被称为全排列
"""
1 2 3 4 ,从中取出3个元素

123
321
231
213
。。。。
"""
#嵌套for循环实现排列
newList3 = []
for i in "ABC":
    for j in "XYZ":
        #print(i + j,end=" ")
        newList3.append(i + j)
print(newList3)
#列表生成式实现排列
list5 = [i + j for i in "ABC" for j in "XYZ"]
print(list5)

#练习:使用列表生成式,将下面列表中的字母全部变为小写
l = ["Hello","GOOD","IBM","word"]

newList4 = []
for s in l:
    newList4.append(s.lower())
print(newList4)

list6 = [s.lower() for s in l]
print(list6)

#存在的问题:如果列表中存在其他类型的元素,比如:数字
l = ["Hello",27,"GOOD","IBM",37,True,"word"]
list7 = [s.lower() for s in l if isinstance(s,str)]
print(list7)
2.生成器

生成器:生成一定数据的容器

意义:Python引入的一个机制,从内存的角度出发,避免生成一批数据造成内存瞬间过大的问题,如果在需要数据的时候,只需要去生成器中获取,生成器会根据提前写好的算法生成一批数据

定义生成器的两种方式

​ a.():将列表生成式中的[]---->()

​ b.yield:借助于函数

#1.
#列表生成式
l = [x for x in range(10)]
#生成器
ge1 = (x for x in range(10))
# print(ge1)
# print(next(ge1))
# print(next(ge1))


#2.
#yield:让步,暂停
def test(n):
    for x in range(1,n + 1):
        yield x
        print(x)
        print("hello")

#注意1:在一个函数中使用yield,相当于设定了返回值,返回的是一个生成器对象
t = test(5)
print(t)
print("获取:",next(t))
print("获取:",next(t))
# for i in t:
#     print("获取:",i)

"""
工作原理:每次调用next函数或者使用for循环获取数据,函数生成器会走到yield会暂停,
将yield后面的值返回,代码停止,只有当下次再调用next或者for循环的时候,函数生成器再从yield下面的代码执行
"""

三、函数递归

递归函数:一个会调用自身的函数被称为递归函数

递归调用:一个函数,调用自身,过程被称为递归调用

递归包含了一种隐式的循环,它会重复执行某段代码,但是这种重复无须条件控制

但凡可以用循环解决的问题,可以递归转换

使用递归解决问题的思路:

​ a.找到一个可以让隐式循环停止下来的临界值

​ b.找到两次循环之间的规律【公式/等式】

#1
# def text():
#     print("fhjadhf")
#     text()
# text()
"""
[Previous line repeated 993 more times]
  File "C:/Users/Administrator/Desktop/XA-Python1807/Day5Code/funcDemo01.py", line 3, in text
    print("fhjadhf")
RecursionError: maximum recursion depth exceeded while calling a Python object
"""

#2.需求:报一个数,输出对应的数,如:5---->5   9---->34
"""
斐波那契数列
1  2 3 4 5 6 7  8  9  10 11
1,1,2,3,5,8,13,21,34,55,89.。。。。。


规律:
1.第一个位置和第二个位置上的数是固定的,都是1 【临界值】
2.第n个位置上的数 = 第n - 1个位置上的数 + 第n - 2个位置上的数


假设func(num)
分析:
func(1) ---- >1
func(2) ----->1
func(3)= func(2) + func(1) = 1 + 1 --->2
func(4) = func(3) + func(2) = func(2) + func(1) + func(2) = 1 + 1 + 1 --->3
...

func(7) = func(6) + func(5)
    func(6) = func(5) + func(4)
        func(5) = func(4) + func(3)
            func(4) = func(3) + func(2)
                func(3) = func(2) + func(1)
        ....

func(n) = func(n - 1) + func(n -2)   n>=3
"""
def func(n):
    print(n)
    if n == 1 or n == 2:
        return 1
    else:
        result = func(n - 1) + func(n -2)
        return  result

print(func(11))

#练习:使用递归计算1~某个数之间所有整数的和
def add1(num):
    total1 = 0
    n = 1
    while n <= num:
        total1 += n
        n += 1
    return total1
print(add1(100))

#递归求和
"""
1+2+3+4+5

add(1) + 0 = 1
add(2)= add(1) + 2
add(3) = add(2) + 3
...
add(n) = add(n - 1) + n

"""
def add2(n):
    if n == 1:
        return 1
    else:
        return  add2(n - 1) + n
print(add2(100))

四、栈与队列

栈【Stack】:限定在表的一端进行插入和删除的线性表,类似于一个开口向上的容器

队列【Queue】:限定在表的一端进行插入,在表的另一端删除的线性表,类似于一个水平放置的水管

线性表:是一种线性结构,同一个线性表中的数据类型相同并且满足一对一的逻辑关系

【面试题:栈和队列的相同点和不同点】

相同点:

​ a.都是线性结构

​ b.插入操作都限定在表尾进行

​ c.管理模式相同

​ d.插入和删除的时间复杂度都是O(1),在空间复杂度上是一样的

不同点:

​ a.删除数据的位置不同,栈的删除在表尾进行,队列的删除在表头进行

​ b.应用场景不同:

​ 栈的应用场景:变量,函数,表达式的转换或者求值

​ 队列的应用场景;计算机中各种资源的分配和管理

#先今后出,后进先出

mystack = []

#压栈【入栈】【向栈中存储数据】
mystack.append(11)
print(mystack)
mystack.append(22)
print(mystack)
mystack.append(33)
print(mystack)
mystack.append(44)
print(mystack)

#出栈【从栈中删除数据】
mystack.pop()
print(mystack)
mystack.pop()
print(mystack)
mystack.pop()
print(mystack)
mystack.pop()
print(mystack)
#先进先出,后进后出

import  collections   #集合

#创建队列
myqueue = collections.deque([11,22,33])


#入队【向队列中添加数据】
myqueue.append(44)
print(myqueue)
myqueue.append(55)
print(myqueue)
myqueue.append(66)
print(myqueue)

#出队【从队列中删除数据】  popleft
myqueue.popleft()
print(myqueue)
myqueue.popleft()
print(myqueue)
myqueue.popleft()
print(myqueue)
myqueue.popleft()
print(myqueue)

五、目录遍历

os:主要操作磁盘上的文件或者目录

1.递归遍历
#递归遍历目录
import  os

def getAll(path):

    #判断指定的路径是否是目录
    if os.path.isdir(path):
        #获取当前路径下所有的内容
        fileList  = os.listdir(path)
        #print(fileList)

        #遍历
        for fileName in fileList:
            #print(fileName)
            #根据已知的路径和文件名称进行路径的拼接
            filePath = os.path.join(path,fileName)

            #判断是否是目录
            if os.path.isdir(filePath):
                print("目录:", fileName)

                #继续判断,获取内部的内容
                getAll(filePath)

            else:
                print("文件:",fileName)

    else:
        print("文件:",path)

if __name__ == "__main__":
    path = r"C:\Users\Administrator\Desktop\XA-Python1807"
    getAll(path)
2.栈模拟递归遍历

深度遍历

#栈模拟递归遍历:每次将目录路径添加到栈中,如果要进一步获取,则将路径从栈中移除【pop】

#递归遍历目录
import  os

def getAll(path):

    if not os.path.isdir(path):
        print("文件:",path)
        return

    #定义一个空栈
    stack = []

    #将初始路径添加到栈中
    stack.append(path)

    while len(stack) != 0:
        #从栈中取出数据,移除的是最后一个元素
        dirpPath = stack.pop()

        #获取初始目录下所有的内容
        fileList = os.listdir(dirpPath)

        #遍历
        for fileName in fileList:
            #拼接路径
            filePath = os.path.join(dirpPath,fileName)

            #判断是否是目录
            if os.path.isdir(filePath):
                #将目录的路径添加到栈中
                print("目录:",fileName)

                #将目录的路径继续添加到栈中
                stack.append(filePath)

                print(stack)

            else:
                print("文件:",fileName)

if __name__ == "__main__":
    path = r"C:\Users\Administrator\Desktop\XA-Python1807"
    getAll(path)

3.队列模拟递归遍历

广度遍历

#队列模拟递归遍历:每次将目录路径添加到队列中,如果要进一步获取,则将路径从队列中移除【popleft】

#递归遍历目录
import  os,collections

def getAll(path):

    if not os.path.isdir(path):
        print("文件:",path)
        return

    #定义一个空栈
    queue = collections.deque()

    #将初始路径添加到栈中
    queue.append(path)

    while len(queue) != 0:
        #从栈中取出数据,移除的是第一个元素
        dirpPath = queue.popleft()

        #获取初始目录下所有的内容
        fileList = os.listdir(dirpPath)

        #遍历
        for fileName in fileList:
            #拼接路径
            filePath = os.path.join(dirpPath,fileName)

            #判断是否是目录
            if os.path.isdir(filePath):
                #将目录的路径添加到栈中
                print("目录:",fileName)

                #将目录的路径继续添加到栈中
                queue.append(filePath)

                print(queue)

            else:
                print("文件:",fileName)

if __name__ == "__main__":
    path = r"C:\Users\Administrator\Desktop\XA-Python1807"
    getAll(path)

六、模块

1.包

作用:

​ a.组织文件

​ b.避免多个文件或者目录命名冲突

区别普通文件夹:init.py文件,为了标记当前文件夹是一个包,前期该文件一般是空的,Django中需要进行项目的配置

2.自定义模块

实质上一个.py文件就是一个模块

模块存在的意义:

​ a.将相同或者相似功能的代码封装到一个模块中

​ b.方便后期的维护

​ c.提高了代码的可读性

​ d.避免函数名和变量名的冲突

​ e.引用其他第三方的模块【系统模块,自定义模块,第三方模块:在使用之前一般需要进行安装】

系统模块:math,os,random,time,datetime等

2.1import

一般常用在系统模块中

点语法:import 包名.模块名

调用函数:包名.模块名.函数名()

#注意:如果要跨文件调用其他文件中的函数或者访问变量,此时需要将其他的文件【模块】导入

#导入系统模块,同时导入多个模块,不同的模块之间的使用逗号隔开
import os,math,random

#注意:导入自定义的模块,一定要注意模块的路径【相对路径】
#相对路径:必须找到一个参照物,参照物为当前的工程
import  aaa.module
import  bbb.module

#导入import:相当于将指定的文件加载了一遍

#调用函数
aaa.module.show()
bbb.module.show()
aaa.module.func2()
2.2from…import

一般使用在自定义模块中

pip:管理第三方模块的

安装:pip install xxx

卸载:pip uninstall xx

#from  包名.模块名 import 函数名或者变量名或者类名
#from aaa.module import show,func1
from aaa.module import *     #将指定模块中的所有的内容【函数,变量,类】全部导入
#from bbb.module import show

#from collections import Iterable

#注意:如果采用from...import方式导入函数,如果两个模块中出现同名的函数,则后导入的函数会覆盖掉先导入的函数
def show():
    print("hello")

show()
func1()

print(num1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值