• Python理论基础知识复习


    Python简介与基础

    Python控制结构

    组合数据类型

    综述
    组合数据类型更能够将多个同类或不同类型组织起来,通过单一的表示使数据更有序、更容易。根据数据之间的关系,组合数据类型可以分为3类:序列类型、集合类型和映射类型。

    • 序列类型是一个元素向量,元素之间的存在先后关系,通过序号访问,元素之间不排他。
    • 集合类型是一个元素类型,元素之间无序,相同元素在集合中唯一存在。
    • 映射类型是键值数据项的组合,每个元素是一个键值对,没有顺序,键唯一存在。
      附:序列类型和映射类型是一类数据类型的总称,不是具体类型。

    序列类型

    序列类型通用函数
    序列类型(元组,字符串,列表都可以使用以下操作)

    操作符 运算
    x (not) in s 是否在内,输出正误
    s + t 连接st,不是按索引求和
    s * t (t * s) 重复
    s[i] 索引
    s[i:j:k] 切片
    len(s) 求长
    min/max(s) 求最值(str比ASCII)
    sum(s) 求和
    s.index(x) x第一次出现的索引
    s.count(x) x出现总数
    sorted(iter, key, reverse) 返回新的排序后序列类型
    reversed() 返回倒序后迭代器,建议再套个list()
    enumerate(A[, start=0]) 返回迭代器,套list()后形成索引与值的元组列表

    ​a = [1,2,3,4] b=a[::-1]这是切片,切片是得到了一个新的列表,属于浅拷贝,对a修改不影响b,反过来也是。

    字符串

    字符串是不可变类型,所以字符串方法不改变原字符串,而是生成新副本。

    函数和处理方法 描述
    str(x) 返回任意类型对应字符串形式
    chr(x) 十六进制/十进制Unicode转单字符
    ord(x) 单字符转Unicode,得到十进制数
    hex(x) 返回整数x对应16进制数小写形式字符串
    oct(x) 返回整数x对应8进制数小写形式字符串
    bin(x) 返回整数x对应2进制数小写形式字符串
    str.lower() 返回副本,全小写
    str.upper() 返回副本,全大写
    str.split(sep=None) 返回列表,str根据sep分隔,默认空格
    str.count(s) 数数
    str.replace(old, new) 返回副本,old都被改为new
    str.center(width, fillchar) 宽度不够就输出全部,居中,fillchar默认空格(可修改为单字符)
    str.strip(chars) 去掉str两侧chars列出的字符
    str.join(iter) 将iter(主体,一种组合数据类型)变量的
    每一个元素后增加一个str字符串(客体)
    a=' '.join(['1','2','3'])  #a = '1 2 3'
    a=' '.join([1,2,3])        #出错
    

    数值类型转换

    #int(x) 
    #str类int/int/float => int
    int('12')     #输出12,支持str类int
    int(12.34)    #输出12,支持float
    int('101',2)  #输出5,进制转换必须str类int
    int('12.34')  #出错
    int('12g')    #出错
    int(12g)      #出错
    int(101,2)    #出错
    int('101.5',2)#出错
    
    #float(x) 
    #int/str类 => float
    float(12)
    float('12')
    float(12.0)
    float('12.0') #都输出12.0
    
    #str(x)
    #int/float => str类
    str(10.01)        #输出'10.01'
    str(1010+101)     #输出'1111'
    str('1010'+'101') #输出'1010101'
    

    列表

    是有序序列,但内部可以更改,列表无长度限制,元素类型可以不同,不需要预先定义长度。
    列表创建方法如下:

    a=[1010,'1010',[1010,'1010']]
    a=list('由字符串生成一个字一个元素')
    a=list() #空列表
    

    由于类型可变
    就有
    ls[i]=k 在原列表修改某个元素
    ls[i:j:k]=lt 在原列表一部分改为新列表

    ls=[i for i in range(6)]
    ls[1:5:2]=['a','b'] #如果个数不对会出错
    print(ls) #输出[0, 'a', 2, 'b', 4, 5, 6]
    

    del [i]/[i:j:k] 删除一部分
    当然也有len(ls) ls.index(x) ls.count(x) x (not) in ls +/* min/max(x) list(x) 等方法操作
    list(x) 将变量x转化为列表类型,可以是字符串、集合也可以是字典(但是形成的是键的列表)

    列表的特殊函数与操作
    由于列表可变,几乎所有方法不需要ls=ls.fn(x),因为原列表已经被改变。
    如果写成l(或者是另外的a变量)=ls.fn(x),只会得到None
    直接ls.fn(x)才是对的。

    函数和处理方法 描述
    ls.append(x) 在最后加元素
    ls.insert(i, x) 在第i位置加元素x
    ls.clear() 清空
    ls.pop(i) 取出并返回第i位置元素并删除,默认最后一个元素
    ls.remove(x) 删除第一次出现的元素x,不返回
    ls.reverse() 元素反转(类比序列方法reversed()
    ls.sort(reverse=False, key=None) 列表排序(类比序列方法sorted()
    str.split(sep=None) 返回列表,str根据sep分隔,默认空格
    str.count(s) 数数
    ls.copy() 例外,生成新列表,浅拷贝

    元组

    不可更改的序列类型(但是元组中可变的元素仍然是可以进行修改的,做字典的键的元组不能含可变的列表、字典、集合),元组可以实现的操作都可以由列表完成,如果不需要修改数据可以把列表换成元组类型,python对元组处理效率高。
    元组创建方法如下:

    a=(1, 2, 3)
    a=1, 2, 3
    a=(1, )
    a=1,
    a=tuple()
    a=()
    #以下错误,括号只能放一个序列类型
    a=tuple(1, 2, 3)
    #以下正确
    a=tuple([1, 2, 3])  #a=[1, 2, 3]
    a=tuple({2:3, 4:5})  #a=[2, 4]
    

    当函数返回多个值,多个返回值以元组类型返回,实际上是返回一个数据类型。

    def f(x):
        return x, x+1, x+2
    print(type(f(1)))  #输出<calss 'tuple'>
    

    集合

    集合中的元素不可重复,元素类型只能是不可变数据类型(整数,浮点数,字符串,元组等),不能是列表,字典,集合。
    集合可以进行数据去重操作。
    集合元素间不能比较和排序。
    空集合用set()表示,对比{}表示空字典

    操作符 运算
    S-T 差集
    S&T 交集
    S|T 并集
    S^T 对称差分

    可以使用S-=T进行增强操作,运算的同时更新S集合

    集合类型常用的函数或方法

    函数或方法 描述
    S.add(x) 把x加到S中(类比列表L.append(x)
    S.remove(x) 移除x,不存在会产生KeyError异常
    S.discard(x) 移除x,不存在也不报错(与上对比)
    S.clear() 移除所有数据但不去除集合本身
    S.pop() 随即返回并删除这个元素来更新S,如果s为set()会产生异常

    其他也有len(S) x (not) in S S.copy()(浅拷贝)等

    字典

    不可变组合类型、基本数据类型可以作为键,元组在各个元素不可变时可做键,列表、集合和其他字典不可做键。
    对字典for i in d遍历时,i是字典的每一个键

    字典函数和方法

    操作符 运算
    d.keys() 返回所有键
    d.values() 返回所有值
    d.items() 返回所有键值对
    d.get(a key, default=) 键存在返回相应值,
    否则返回默认
    增加新键值对
    d.pop(a key, default=) 键存在返回相应值
    并删除键值对
    否则返回默认
    d.popitem() 随机取出键值对,以元组返回并删除键值对
    d.clear() 成为空字典
    del d[x] 删除以x为键的键值对

    注意:keys,values,items方法返回的是特殊的内部数据类型,想更好的使用返回数据最好利用list()转化成列表,键值对以元组类型储存在列表里。
    字典与序列类型类似的通用操作
    in 判断一个键是否在字典中
    len(d)字典键值对数量
    min/max(b) 返回最小最大的索引值(前提是字典中各个索引元素可以比较)

    字典的索引

    print(d[x]) #输出x对应的键
    d[x] = 1 #修改字典键值对,也可以增加新键值对
    

    字典创建方法如下:

    a={'1':2, '3':4}
    a=dict()
    a={}
    #错误方法
    a={(1,2), (3,4)} #创建的是含两个元组的集合
    #正确方法可使用dict(),这个括号里只能有一个大类,大类里有小类,每个小类两个元素(长为2)
    a=dict(([1,2], [3,4]))
    a=dict([((1,2),2), ((3,),4)])
    

    深拷贝与浅拷贝

    jjzz1234的博客

    python中,变量与变量的值占用不同的内存。变量占用的内存,并非直接存储数值,而存储的是值在内存中的地址。

    ls = ['中国','矿业','大学']
    ls1 = ls           #ls1 = ls 实际上是ls1指向了ls指向的地址块,两者指向的是同一块地址区域,不是拷贝
    print(ls1)         #输出ls = ['中国','矿业','大学']
    ls.append('憨憨')   #对ls进行元素操作时,也是对ls1造成影响
    print(ls1)         #输出['中国', '矿业', '大学', '憨憨']
    ls2 = ls[:]        #利用切片,在内存中新建了一个列表,ls2指向这个新的列表,浅拷贝
    print(ls2)         #输出ls = ['中国','矿业','大学', '憨憨']
    ls.append('憨包')   #对ls的元素进行任何操作,都不会影响ls2的内容
    print(ls2)          #输出ls = ['中国','矿业','大学', '憨憨']
    

    a = 1 b= a这不是拷贝,赋值是多个变量指向同一个内存地址,内存的任一元素改变,所有变量都受影响
    ​a = [1,2,3,4] b=a[:]这是切片,切片是得到了一个新的列表,属于浅拷贝

    浅拷贝x.copy()

    对只有一层元素关系的列表进行测试:

    ls = ['python','c','cpp']
    ls1 = ls.copy()
    print(id(ls),id(ls1))    #输出  2551633171528 2551633985416,可见二者指向的内存地址不同
    ls.append('php')
    ls1.append('java')
    print(ls)            #输出 ['python', 'c', 'cpp', 'php'],对ls的append操作没有影响ls1
    print(ls1)			#输出 ['python', 'c', 'cpp', 'java'],对ls1的append操作没有影响ls
    

    从以上结果可得:在copy完之后,新的列表指向新的内存地址,分别对列表的最后一位进行appen操作,结果互不影响。

    对具有二层的元素的列表进行测试:

    ##对ls的第二个元素进行append操作
    ls = ['德玛',['费欧娜','戴安娜'],'赵信']
    ls1 = ls.copy()             
    print(ls1)				    #输出['德玛', ['费欧娜', '戴安娜'], '赵信']
    ls[1].append('莫甘娜')       #copy完成后对ls的第二个元素进行append操作
    print(ls1)           #输出'德玛', ['费欧娜', '戴安娜', '莫甘娜'], '赵信'],ls1发生了改变
    print(id(ls[1]),id(ls1[1]))  #查看两者的ID,2202073060424 2202073060424
    
    ##对ls1的第二个元素进行操作
    ls = ['德玛',['费欧娜','戴安娜'],'赵信']
    ls1 = ls.copy()
    print(ls)			    #输出['德玛', ['费欧娜', '戴安娜'], '赵信']
    ls1[1].append('莫甘娜')	#copy完成后对ls1的第二个元素进行append操作
    print(ls)			#输出'德玛', ['费欧娜', '戴安娜', '莫甘娜'], '赵信'],ls发生了改变
    print(id(ls[1]),id(ls1[1]))  #输出 2303581443144 2303581443144
    

    从上边输出的结果来看,copy完成之后,分别对ls和ls1的中间元素进行append操作,对方的元素也会发生相应的改变。

    结论:浅拷⻉, 只会拷⻉第⼀层内容,只拷贝第二层关系的内存地址,而第⼆层的内容不会拷贝,所以被称为浅拷贝。

    深拷贝x.deepcopy()

    深拷贝使用之前一定要先加载copy模块

    import copy
    new_ls = copy.deepcopy(ls)
    

    实例:

    #对ls进行二层操作
    import copy
    ls = ['德玛',['费欧娜','戴安娜'],'赵信']
    ls1 = copy.deepcopy(ls)
    ls[1].append('莫甘娜')
    print(ls)   #输出['德玛', ['费欧娜', '戴安娜', '莫甘娜'], '赵信']
    print(ls1)  #输出['德玛', ['费欧娜', '戴安娜'], '赵信']
    
    #对ls1进行二层操作
    import copy
    ls = ['德玛',['费欧娜','戴安娜'],'赵信']
    ls1 = copy.deepcopy(ls)
    ls1[1].append('莫甘娜')
    print(ls)  #输出['德玛', ['费欧娜', '戴安娜'], '赵信']
    print(ls1)  #输出['德玛', ['费欧娜', '戴安娜', '莫甘娜'], '赵信']
    

    由以上结果可得:深拷贝是完完全全的复制,是创建一个完完全全的新的对象,新旧对象之间不会相互影响。不可变数据类型新旧列表指向同一个空间,可变类型新列表创建了新的空间

    另附:

    a = [1, 2]
    a[1] = a   #对a列表的第二个元素进行修改成自己
    print(a[1])  #输出为[1, [...]]
    print(a)  #输出为[1, [...]]
    print(id(a),id(a[1]))  #输出内存地址1191853053000 1191853053000  a与a[1]的内存地址一样
    print(type(a[1]))  ##输出<class 'list'>
    

    分析: a[1] 原来是int类型,在对a[1]进行修改操作时,会先把原来的指向剪断,因为赋值a,指向了自己,此时出现了数据上的死循环。

    函数

    参数

    参数及其传递

    #向函数传递信息
    def greet_user(username):  #username是形参
        print("hello," + username + "!" )
    
    greet_user('python')  #'python'是实参
    

    在函数名中定义一个形参,函数调用时,给函数名中的形参传递实参。
    传递实参的方法有:

    • 位置实参(按照基于实参的顺序关联到形参,有顺序)
    • 关键字参数(类似按照键值对,按照名字进行关联,无顺序问题)
    • 默认值参数(给形参进行固定值作为默认值,如果没有提供实参对默认值进行覆盖处理,则代入默认数值后运行函数)
      注意:
    • 两种传参方式可以混合使用,但使用时关键字参数必须位于位置参数之后

    可变参数*args与**kwargs

    fengmk2博客相关内容

    def f(*args, **kwargs):
        print('args = ', args)
        print('kwargs = ', kwargs)
        print()
    
    if __name__ == '__main__':
        f(1,2,3,4)
        f(a=1,b=2,c=3)
        f(1,2,3,4, a=1,b=2,c=3)
        f('a', 1, None, a=1, b='2', c=3)
    

    输出结果是

    args =  (1, 2, 3, 4)
    kwargs =  {}
    
    args =  ()
    kwargs =  {'a': 1, 'c': 3, 'b': 2}
    
    args =  (1, 2, 3, 4)
    kwargs =  {'a': 1, 'c': 3, 'b': 2}
    
    args =  ('a', 1, None)
    kwargs =  {'a': 1, 'c': 3, 'b': '2'}
    

    这是python中的两种可变参数。

    • *args表示任何多个无名参数,它是一个tuple
    • **kwargs表示关键字参数,它是一个dict
    • 同时使用*args**kwargs时,*args参数必须在**kwargs前,像f(a=1, b='2', c=3, a', 1, None)这样调用的话,会提示语法错误SyntaxError: non-keyword arg after keyword arg

    等效的函数调用

    函数调用时,无论是使用位置参数还是关键字参数、默认值参数,得到的结果都是一样的。

    #一个名为harry的小狗
    def describe_pet(pet_name,animal_type = 'dog'):
        函数省略
    describe_pet(pet_name="harry")
    describe_pet("harry")
    

    两次使用describe_pet()函数的结果一致

    全局变量和局部变量

    1. 这是两种不同的变量
    • 局部变量是函数内部的占位符,与全局变量可能重名但是不同
    • 函数运算结束后,局部变量被释放,不再进行储存
    • 可以使用global保留字,从而在函数内部使用全局变量
    1. 局部变量为组合数据类型且未创建,等同于全局变量
    ls=['x', 'y']  #真实创建了一个ls全局变量列表
    def f(n):
        ls.append(n)  #ls是列表类型,没有真实创建,等同于全局变量
        return  #加不加return都是一样的
    f('z')  #全局变量被修改
    print(ls)
    

    以上输出为['x', 'y', 'z']

    ls=['x', 'y']  #真实创建了一个ls全局变量列表
    def f(n):
        ls = []  #ls是列表类型,真实创建,在这里ls是局部变量
        ls.append(n)
        return  #加不加return都是一样的
    f('z')
    print(ls)
    

    以上输出为['x', 'y']
    规则总结

    • 基本数据类型,无论是否重名,局部变量与全局变量不同
    • 可以通过global保留字在函数内部声明全局变量
    • 组合数据类型,如果局部变量未真实创建,则是全局变量

    另附:

    • return在不带参数的情况下(或者没有写),默认返回None

    文件

    数据分析与爬虫

    内库与三方库

  • 相关阅读:
    Ansible专题整理
    前端基础之JQuery
    Three.js开发指南---创建,加载高级网格和几何体(第八章)
    Three.js开发指南---粒子和粒子系统(第七章)
    Three.js开发指南---使用高级几何体和二元操作(第六章)
    Three.js开发指南---学习使用几何体(第五章)
    Three.js开发指南---使用three.js的材质(第四章)
    Three.js开发指南---使用three.js里的各种光源(第三章)
    Three.js开发指南---使用构建three.js的基本组件(第二章)
    -Three.js开发指南---用three.js创建你的第一个三维场景(第一章)
  • 原文地址:https://www.cnblogs.com/hujunyao37201/p/13202478.html
Copyright © 2020-2023  润新知