python笔记(二)

  • python实现九九乘法表

"""while循环实现九九乘法表"""
right = 1
while right <= 9:
    left = 1
    while left <= right:
        print(f"{left}x{right}={left * right}", end='\t')
        left += 1
    print()
    right += 1


"""for循环实现九九乘法表"""
for right in range(1,10):
    for left in range(1,right+1):
        print(f"{left}x{right}={left * right}", end='\t')
    print()
  • python实现石头剪刀布

import random

"""石头剪刀布--基础版"""
computer = random.randint(0, 2)
player = int(input("请出拳(0:石头 1:剪刀 2:布):"))

drr = {0: "石头", 1: "剪刀", 2: "布"}
print(f'玩家输入: {drr[player]}, 电脑出拳: {drr[computer]}')
if computer == player:
    print("平手!")
elif computer - player in (-1, 2):
    print("电脑胜利")
else:
    print("玩家胜利")



#  石头剪刀布--优化版
drr = {0: "石头", 1: "剪刀", 2: "布"}
# 轮次
epoch = 1
while True:
    # 三局两胜
    success_c = 0
    success_p = 0
    for i in range(1, 4):
        computer = random.randint(0, 2)
        # 判断用户输入是否是数字 以及是否在字典里
        while True:
            player = input(f"第{epoch}轮{i}局 请出拳(0:石头 1:剪刀 2:布):")
            if player.isdigit() and int(player) in drr:
                player = int(player)
                break
            print("输入错误,请重新输入....")

        print(f'玩家输入: {drr[player]}, 电脑出拳: {drr[computer]}')

        # 每一局判定胜负
        if computer == player:
            print(f"第{epoch}轮{i}局平手!\n")
        elif computer - player in (-1, 2):
            print(f"第{epoch}轮{i}局电脑胜利\n")
            success_c += 1
        else:
            print(f"第{epoch}轮{i}局玩家胜利\n")
            success_p += 1

        # 如果有一方一开始连胜两局,第三局就不需要玩了
        if 2 in (success_c, success_p):
            break
    # 本场胜负判断
    if success_c == success_p:
        print(f"第{epoch}轮两局三胜平手\n")
    elif success_c > success_p:
        print(f"第{epoch}轮两局三胜电脑胜利\n")
    else:
        print(f"第{epoch}轮两局三胜玩家胜利\n")

    # 是否继续
    while (isContinue := input("是否继续?Y(是)/N(否)")) not in ('y', 'Y', 'n', 'N'):
        print("输入错误,请重新输入....")

        # 结束
    if isContinue in ('n', 'N'):
        print("欢迎下次光临")
        break
    epoch += 1
  • 推导式 二维数组列变行

# 正常处理 将二维数组列变行
lst = [[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9],
       [10, 11, 12]]
lst_new = []
for x in range(len(lst[0])):
    print(x)
    item = []
    for y in lst:
        print(y)
        item.append(y[x])
    print(item)
    lst_new.append(item)

print(lst_new)


# 推导式
lst = [[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9],
       [10, 11, 12]]
lst_new = [[y[x] for y in lst] for x in range(len(lst[0]))]
print(lst_new)
  • 条件运算

       条件语句

                         if 判断条件1:
                            执行语句1...
                        elif 判断条件2:
                            执行语句2...
                        else:
                            执行语句4...


    if 0 == None (结果为false)
    if 0 | [] |  结果为false
    小整数池 除了 -5--256 ,还包含 None、True、False

random模块常用函数

     random.random()  返回[0.0 - 1.0] 随机浮点数 不包含1.0
    random.randint(a,b) 返回[a,b] 随机整数(a>b)
    random.uniform(a,b) 返回[a,b]/[b,a] 随机浮点数,自动比较大小
    random.choice(seq)  非空序列返回随机元素,seq为空时报错
    random.sample(pop,k)pop:总样本序列或集合, k:取几个,以列表方式返回(不放回)
            py3.9 集合采样已弃用(集合不属于序列)
    random.shuffle(x) 将可变序列(列表、集合、字典) 随机打乱位置,原地操作
    random.randrange([start],end,[step]) 左闭又开 [start,end]  随机返回一个元素
    random.seed([x]) 固定随机数的作用,x可以时任意数字,可以理解为种子
        x为空时解除固定随机数

range([start],end,[step]) [start,stop,step] 左闭右开
    返回数据为range(start,end) 切片之后还是range,可以转元组和list
    是序列,不可变,是可迭代对象(和元组、字符串)
    步长为正数 start-end必须从小到大
    步长为负数 start-end 必须从大到小
    优势:数据量比较大时,存储在元组或list中会占用较大内存,range 只存start、end、step,不占用内存

循环

while 循环

        while 判断条件:
            执行语句...
        死循环 while true

for循环

        (一)for i in (可迭代对象):(获取元素)
            执行语句....
        (二)for i in (len(可迭代对象)):(获取索引)
              执行语句....
        # 获取索引和元素
        (三)for index, item in enumerate(lst):
              执行语句.....
            enumerate(可迭代对象,start =0)枚举 
                返回迭代器,转list之后 [(索引,元素),(索引,元素),(索引,元素)]
        for循环....else 不冲突
        for后面的标识符没有用到的时候 用"_"代替,里面也是有值的 

跳过循环

        break 结束所在循环
        continue 结束本次循环
        pass 空操作,什么都不执行(可临时占位)也可以用...

  • 推导式

        列表推导式

                [表达式 for子句]
                [表达式 for子句 更多的for子句或if子句]
                lst = [x for x in range(9, 1, -2)]

        字典推导式

                 {k:v for子句}
                {k:v for子句 更多的for子句或if子句}
                d = {x: x + 1 for x in range(9, 1, -2)}

        集合推导式

                {表达式 for子句}
                {表达式 for子句 更多的for子句或if子句}
                s = {x for x in range(9, 1, -2)}
                s = {x + y for x in range(5) for y in range(1, 4)}

  • list、dict、set的迭代问题:

        字典在迭代期间 不允许个数发生改变,可以修改数据,必须保证size不发生改变

        集合在迭代期间 不允许改变size

        列表遍历期间 删除清空全部元素时,达不到效果(遍历中元素发生改变 会导致下标发生变化),需要拷备份数据进行遍历
   

  • 函数

        自定义函数格式:

                def func_name([arg1, arg2...]):
                    func_body...
            --函数在定义时,不会执行函数提
            --函数在被调用时,才会执行函数体
            --函数只需要被定义一次,可以被多次调用

 调用函数格式

                func_name([实参1, 实参2...])

函数的好处

        --结构性比较清晰
        --代码简化,提高可复用性


    函数是否有返回值由return决定

return的作用:

         -将return后面的对象返回给函数的调用放
         -结束return所在的函数


    return后面可以跟单个/多个对象/表达式,
            不跟就返回None
    如果函数被调用,没有执行到return,等价于return None

    breake/pass/continue/return
        相同:都是关键字,
        不同:return结束函数体,break结束循环

文档注释:

        func__doc__ 输出文档注释
        help([obj]) 输出obj的帮助信息  help()命令行启动帮助界面
        __annotations__ 以字典的形式存放在函数属性

数学相关的内置函数

        max 取最大值
            max(可迭代参数,[key,default])
            max(arg1,arg2,*arg,[key])  arg最少为两位
        min 取最小值,用法同max
        pow(base, exp, [mod])
            base的exp次幂,mod存在时对米的结果取模
        round(num,[ndg]) 四舍五入
            ndg:保留的小数点位数,不存在保留整数位
            会保留符号,
            -精确到整数位时(0.5 1.5 2.53.5),如果是中间的话(0.5),遵循从偶规则

        abs(num) 取绝对值
        sum(可迭代参数,/,start=0) 求和
            -/ * 都为特殊参数,不接受实参
            -start 累计相加的开始的数字

    类型标注

        变量类型会随着着变量随之改变,python属于弱类型语言
        变量: 类型 定义变量的类型 -> 返回类型标注

    导入的两种方式

        import numbers
        from random import randint (random没有导入 可以直接使用randint,导入多个可以用逗号隔开
                from random import randint, randrange, shuffle )

    参数分类

        必需参数
            必须参数可以传位置参数也可以传关键字参数
        位置参数 和顺序有关
        关键字参数 和位置无关
            关键字参数必须放在位置参数之后
        默认参数 如有实参,优先接受实参,没有实参则使用自己的默认值
            默认参数必须放在必需参数的后面
        不定长参数
            - *arg 接收[0,+∞)个位置参数,贪婪,打包成一个元组,没有实参输出空元组
            - **kwargs 接收[0,+∞]个关键字参数,贪婪,打包成一个字典,没有实参输出空字典

        特殊参数
            / * 特殊参数不接收实参
            限制传参的格式
            *的作用 *后面的参数必须为关键字参数
            /的作用  限制/前面的实参必须为位置参数

    匿名参数

        定义:lambda [arg1,arg2...]: 一个表达式
        调用匿名函数:
            func_name = lambda [arg1,arg2...]: exp
            func_name([实参1,实参2...])
            (lambda[arg1,arg2])([实参1,实参2...])
        匿名函数没有return,参数可以有多个但表达式只有一个
        匿名函数可以在需要函数对象的任何地方使用(如:赋值给变量、作
为参数传入其他函数等),因为匿名函数可以作为一个表达式,而不
是一个结构化的代码块
        匿名函数没有传参数 直接写 lambda: 表达式

  •     封包

         将多个值赋值给一个变量时,Python 会自动将这些值封装成元组,这
个特性称之为封包
        a = 1,2,3,4 输出a 为元组(1,2,3,4)
        多目标赋值 a=b=c=d = 1

  • 解包

        针对所有的可迭代对象

        取值过程中的解包

                a,b,c,d = [1,2,3,4] 序列赋值本质上是解包
                等号两边不等长时,参数前加*号 相当于*arg,但不贪婪,会将数据打包成list,变量里的*只能存在一个

        传实参中的解包

                调用函数时,传入可迭代参数时 可以用单个* 函数内会解包
                可迭代参数是 字典时,可以用**,函数会按照key获取值

           

  • 递归实现兔子问题

# 兔子问题 兔子过了两个月就会生 第n个月会有多少只兔子
# 规律 前两个月的兔子数量相加等于第三个月的兔子数量
# 递归实现 m:月份
# 递归缺点是会重复大量计算,次数较多时计算会很慢
import sys

store = {}


def get_rabbit(m):
    if m < 2:
        return 1
    # 将重复计算的数据存储在字典中,避免大量重复计算
    if m in store:
        return store[m]
    res = get_rabbit(m - 1) + get_rabbit(m - 2)
    store[m] = res
    return res


sys.setrecursionlimit(1001)  # 放宽递归最大深度
print(sys.getrecursionlimit())  # 查找递归最大深度限制
print(get_rabbit(45))
# print(store)


# 循环实现
def func(m):
    m0 = m1 = 1
    for _ in range(m - 1):
        m0, m1 = m1, m0 + m1  # 序列赋值
    return m1
    # 循环m次返回m0 循环m-1次返回m1


print(func(6))
  •   命名空间

                命名空间是 从名称到对象的映射,以字典方式实现
                作用: 避免名字冲突(同一命名空间中不能重名,不同命名空间可以重名而没有影响)

        内置命名空间

                    解释器启动时创建,持续到解释器终止
                    由builtins模块实现
                    dir([obj])
                        obj不传 返回当前模块定义的标识符名称构成的str类型的list
                        传obj-返回obj下面定义好的属性、方法列表

      全局命名空间

                 在模块读入时创建,持续到解释器退出
                 针对某一个py文件
                 记录模块的函数、变量、类、其他导入的模块
                 globals()  # 返回当前的全局命名空间--字典类型 名称:对象

        局部命名空间

                在函数被调用时创建,持续到函数结束
                记录函数里的变量和参数 ---针对函数
                locals() 返回当前的局部命名空间 --字典
                全局的locals等价于globals
        命名空间查找顺序
            局部--> 全局 --> 内置 --> 没找到报错
        将字符串当作python程序执行
            eval(exp,[globals,locals])
                返回exp的返回值,针对单行
            exec(obj,[globals,locals])
                无返回值,针对多行字符串
                globals 指定全局命名空间 locals指定局部,locals被忽略,取相同的globals

   

  • 作用域

        定义: python程序可以直接访问命名空间的正文区域
        作用: 决定了那一部分区域可以访问哪个特定的区域
        分类:(L - E - G - B 作用域依次增大)
            局部作用域(Local) - L
            闭包函数外的函数中(Enclosing) - E(闭包函数里的内部函数与外部函数之间的距离)
            全局作用域(Global) - G
            內建作用域(Built-in) - B
        作用域查找规则: (built > globals > enclosing > local)
            在当前作用域找不到对应名称,取更大一级作用域去找,最后找不到就会报错(不能往 小了找,enclosing、local可以有多个,global只能有一个)
        只有函数、类、模块 会引入作用域,推导式会引入新的作用域
        条件语句、循环语句不会引入新的作用域

       

global 和 nonlocal区别


            -- global 变量名 声明当前作用域的变量a全部为全局变量
            -- nonlocal 变量名 声明当前作用域的变量a全部为enclosing变量

闭包函数

        一般来说,闭包函数需要满足3个条件
            --首先需要是嵌套函数
            --外部函数的返回值是内部函数的引用
            --内部函数用到了外部函数的变量或形参

   

  • 常用高阶函数

        定义:参数或返回值为其他函数的函数(闭包函数属于高阶函数)
                对返回值进行操作


        filter(function,iterable)  --过滤,属于内置类型

         function 函数,或者None(必需参数)
            iterable 可迭代对象
            --将iterable 中的每个元素依次作为实参传递给 所指定函数去调用
            --返回值进行bool判定,为True的留下,为False的去掉,最后映射到元数据(function传None时,是对可迭代对象中的每个元素直接进行bool判定)
            --返回数据为迭代器,可以用list转列表

map(function,*iterable)

        func:必需,必须为可接受n个可迭代对象的函数
            *iterable:(n)多个可迭代对象(不定长参数)
            --拉链操作 将可迭代1..可迭代2..参数相邻进行函数调用(以最短的可迭代对象为准)
            --返回值为 迭代器,用list转列表


        reduce(func,iterable,[initial])

                --需要先导入包 from functools import reduce
            --返回值 非迭代器
            --func 必须为可接受两个实参的函数 initial:初始值,从初始值开始,再拿一个元素进行func调用
            -(无初始值)先拿两个参数进行func调用,用结果和后面一位进行func调用...循环
            -初始值+元素数量等于1时,返回该元素,当均无元素时 会报错
           

  • 递归函数(了解)

        定义: 程序调用自身的编程技巧成为递归
        递归函数要满足2个条件:
            递归边界条件(一般到递归边界则终止当前递归)
            递归推理(一般是提取重复的子问题,不断向递归边界靠拢或者不断
缩小问题规模)
        递归默认的最大深度限制是 1000
        先import sys
        sys.setrecursionlimit(1001)  # 放宽递归最大深度
        sys.getrecursionlimit()  # 查找递归最大深度限制

  • 面向过程编程

     更加注重算法,注重任务完成的过程,符合人的思维逻辑
         特点: 可读性比较好、易于阅读、思维比较简单
        缺点: 结构不够明显、不宜于修改
        比较符合任务量较小 代表语言:C语言

  • 面向对象编程

    重数据轻逻辑,实现程序解耦
    特点: 高内聚 低耦合
    类是抽象的

程序 = 算法 + 数据结构


类, 类对象(大驼峰命名)
    实例化: 类对象()
    输出实例化后的对象会输出__main__
        __main__ 指的是当前这个模块
        间接执行py02(其他文件引入py02 ) 输出类对象时,会输出模块名.student

    方法: 类里面的函数称之为方法
    魔术方法: (特殊方法) 官方定义好的以两个_开头和结尾命名的方法
        特点:一般不需要主动调用,在特定情况下会自动调用

    __new__(cls, *args, **kwargs): 构造方法, 实例化时自动调用(先)
    __init__(self): 初始化方法,  实例化自动调用(后)                无返回值
    实例化过程: 每一次实例化时,会自动调用__new__方法,将实例化操作的类对象(即student) 作为实参传递给形参cls
        实例化操作传入的其他实参传给形参 *args, **kwargs,然后__new__会根据cls构造出一个实力对象并返回

        接着,又自动调用__init__方法,把__new__构造的实例对象(即stu1)作为实参传递给形参self, 实例化操作传入的其他实参传给形参,
        然后__init__就可以对该实例对象进行属性定制操作(原地操作 inplace)
    实例对象是由构造方法__new__创建并返回的,初始化方法__init__只是做属性定制,所以 __init__不能用返回值(return None)
    所有类都默认继承object
    实例对象属性定制的变量 叫实例属性(实例变量) 独有的

    类属性(类变量): 将变量绑定给类对象 叫做类属性 共有的
    属性的增删改查:
        调用
            实例属性
                --实例对象.属性名称(只能用实例对象调用)
            类属性:
                --既可以类对象调用(推荐),也可以用实例对象调用
                --注意:如果调用的实例属性和类对象同名,则实例对象优先调用实例属性
                --实例属性不存在时,会用type调用实例对象调用类属性
        修改
            实例属性
                --只能用实例对象修改
                --stu1.name = '新名称'
            类属性:
                --只能用类对象修改
                --注意:不能用实例对象修改类属性 会给该实例动态定义实例属性
        动态定义实例属性:
            用实例对象定义不存在的实例属性时, 会动态增加 实例属性
        动态定义类属性:
            用类对象定义不存在的类属性时, 会动态增加类属性
        删除
            del

    属性操作相关内置函数
        delattr(obj,name)
            删除object的name属性, name指定为str
            object可以为实例对象,也可以为类对象
        getattr(obj,name,[default])
            获取object的name属性
        hasattr(obj,name)
            判断obj里的name是否存在,存在返回True,不存在返回False
        setattr(obj,name,value)
            将obj里的name属性设置为value  原地操作无返回值
            存在就修改,不存在就动态增加
功能
    对象方法
        第一个参数位隐式接收了实例对象。第一个参数是self
        既可以用实例对象调用(推荐),也可以用类对象调用
        注意:如果用类对象调用,self不会自动实例化类对象,需要主动传递实参
    类方法
        与对象方法不同,方法前面加装饰器   @classmethod # 内置的类方法装饰器
        调用类方法,类方法默认第一个参数为cls
        既可以用类对象调用(推荐),也可以用实例对象调用
        注意:如果用实例对象调用类方法,本质上是在用实例对象的type(即Student)在调用 类方法
    静态方法
        @staticmethod 内置的静态方法装饰器
        既可以用类对象调用(推荐),也可以用实例对象调用

    选择方法:
        不同的self不同的效果 使用对象方法 独特性
        共性的可以使用类方法或者静态方法
       

面向对象的三大特性
    封装
        将属性前面添加 '__',将属性封装为 私有属性(只能在类内访问)
        在方法面前添加'__',将方法封装为 私有方法
        可以简介访问: 通过非私有化方法简介访问 私有方法或私有属性
        python运行时,将__school 改为_Student__school,在类外调用不到
        就算是继承关系,子类也无法直接访问父类的私有属性和私有方法(可间接访问)
    继承
        所有类默认继承object父类, 一般不写出来
        继承分为 单继承(A->B->C A->C A->B) A(基类、父类、超类)
                多继承(A、B -> C) 多继承从左往右找
        继承顺序 先找自己->找父类(多继承从左往右 找到底object)
        对象的继承查找顺序: 类对象.__mro__
        优点及意义:对于子类而言,继承可以简化代码,对于父类而言,子类是父类功能的扩充

        子类重写父类的方法后,需要再次调用父类的方法可以用super表示父类超类(前提 存在继承关系)
            super(要调用哪个类的父类, 用哪个对象调用).method()
            super(要调用哪个类的父类, 用哪个对象调用).属性attr
            类内的方法进行调用父类方法时,可以用super().方法() (不推荐)
        继承相关的内置函数
            isinstance(obj,classinfo)
                判断obj是否是classinfo 的实例对象或者子类的实例对象(考虑继承)  相当于type(obj) == A 但type不会考虑继承关系
                classinfo 可以为元组,一个满足就满足
                返回bool值
            issubclass(class,classinfo)
                判断class是否是classinfo的子类
                classinfo可以为元组,满足一个就成立
                类是自身的子类,
    多态
        具有不同内容的方法可以使用相同的方法名,则可以用一个方法名调用不同内容的方法

    type(obj) 返回obj
    type(name,bases,dict) 创建一个新类型

    python里一切皆对象
    所有类都默认继承object
    object是所有类的父类,type、object 也是是object的子类
    所有的类都是type类的实例对象,所以type、object也是type的实例对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值