• python字符编码、字符串格式化、字符串方法、列表、元组、字典、集合等基础知识总结


    目录:

    一、字符编码

    二、字符串格式化

    三、进制转换

    四、数据类型及其操作 1.int类、2.str类

    五、格式转换

    六、For循环

    七、三元运算

    八.列表

    九、列表推导式

    十、元组

    十一、字典

    十二、集合set

    十三、文件操作

    十四、变量指向和深浅拷贝

    .字符编码:

    计算机由美国人发明,最早的字符编码为ASCII,只规定了英文字母数字和一些特殊字符与数字的对应关系。最多只能用 8 位来表示(一个字节),即:2**8 = 256,所以,ASCII码最多只能表示 256 个符号

    ascii用1个字节代表一个字符;

    unicode常用2个字节代表一个字符,生僻字需要用4个字节;

    UTF-8英文字母被编码成1个字节,汉字通常是3个字节有很生僻的字符才会被编码成4-6个字节。

    字母x,用ascii表示是十进制的120,二进制0111 1000

    汉字中已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。

    字母x,用unicode表示二进制0000 0000 0111 1000,所以unicode兼容ascii,也兼容万国,是世界的标准

    这时候乱码问题消失了,所有的文档我们都使用但是新问题出现了,如果我们的文档通篇都是英文,你用unicode会比ascii耗费多一倍的空间,在存储和传输上十分的低效

    本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

    字符

    Ascll

    Unicode

    Utf-8

    x

    01000001

    00000000 01000001

    01000001

    不能表示

    01001110 00101101

    11100100 10111000 10101101

    从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

    ASCII:只能存英文和拉丁字符,一个字符占一个字节,8位

    gb2312:只能存6700多个中文,1980年

    gbk1.0:存2万多字符,1995年

    gb18030:存27000中文,2000年

    万国码:Unicode:utf-32  一个字符占4个字节

                     Utf-16  一个字符占2个字节,或两个以上。

                     Utf-8   一个英文用ASCII码来存,一个中文占3个字节

    声明编码  -*- coding:utf-8 -*-

    gbk默认不认识utf-8,utf-8是Unicode的一个子集

    Unicode 默认向下兼容gbk等

    python3内部默认是 unicode,文件默认编码是utf-8

    阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII

    ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符

    ASCII最初只用了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符),后来为了将拉丁文也编码进了ASCII表,将最高位也占用了

    阶段二:为了满足中文和英文,中国人定制了GBK

    GBK:2Bytes代表一个中文字符,1Bytes表示一个英文字符

    为了满足其他国家,各个国家纷纷定制了自己的编码

    日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里

    阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。如何解决这个问题呢???

    说白了乱码问题的本质就是不统一,如果我们能统一全世界,规定全世界只能使用一种文字符号,然后统一使用一种编码,那么乱码问题将不复存在,

    很多地方或老的系统、应用软件仍会采用各种各样的编码,这是历史遗留问题。于是我们必须找出一种解决方案或者说编码方案,需要同时满足:

    1、能够兼容万国字符

    2、与全世界所有的字符编码都有映射关系,这样就可以转换成任意国家的字符编码

    这就是unicode(定长), 统一用2Bytes代表一个字符, 虽然2**16-1=65535,但unicode却可以存放100w+个字符,因为unicode存放了与其他编码的映射关系,准确地说unicode并不是一种严格意义上的字符编码表

    很明显对于通篇都是英文的文本来说,unicode的式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)

    阶段四:于是产生了UTF-8(可变长,全称Unicode Transformation Format),对英文字符只用1Bytes表示,对中文字符用3Bytes,对其他生僻字用更多的Bytes去存。

    . Python 字符串格式化

    Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。

    格式输出汇总:

     1 #第一种
     2 val = "我叫%s,今年%d岁,身高%d"%('zrh',20,175)
     3 print(val)   #运行结果:我叫zrh,今年20岁,身高175
     4 #第二种
     5 val = "我叫{0},今年{1}岁,身高{2},我弟弟身高也是{2}"
     6 val1 = val.format("zrh",20,175)
     7 print(val1) #运行结果:我叫zrh,今年20岁,身高175,我弟弟身高也是175
     8 #第三种
     9 v = input("your name:") #用户输入姓名
    10 val = "我叫{name},今年{age}岁,身高{height}"
    11 val1 = val.format(name=v,age="20",height="175") #name = v是用户输入的那个姓名
    12 print(val1)
    13 #第四种
    14 val = "我叫{name},今年{age}岁"
    15 dic1 = {"name":"zrh","age":20}
    16 val1 = val.format(**dic1)
    17 print(val1)
    18 #第五种
    19 name = "我叫{name},年龄{age}"
    20 val = name.format_map({'name':'海角','age':18})   #只有一种写法,里面必须是字典
    21 print(val)

    如果在格式化输出中想要输出%号,就要用到%%格式

    print("我是%s,我的进度已经完成80%%" %('zrh'))

    输出结果:

    我是zrh,我的进度已经完成80%

    %06d表示数字用6位表示,数字不足6位的话用0代替

    from math import *
    a = log(e**2)
    print('%.2f'%(a))  #输出结果:2.00

    百分号的输出:

    num = 0.1
    print("数据比例为 %.2f%%"%(num*100))
    #输出结果:数据比例为 10.00%

    变量名关键字:

    python在定义变量名时区分大小写

    import keyword as kw
    print(kw.kwlist)
    #['False', 'None', 'True', 'and', 'as', 'assert', 'async', 
    # 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 
    # 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 
    # 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 
    # 'try', 'while', 'with', 'yield']

    转移符号相关问题:

    \t 表空格

    \n表换行

    如果字符串中需要输出\n、\t等,需要加两个\\

    print("\\n")  #输出结果 \n

    如果字符串中需要输出的“\”非常多的话,可以使用原始字符串模式打印,即在字符串前输入r

     

    如果字符串超过一行,再给变量赋值时需要使用三引号

    case = '''
    超过一行的字符串
    '''

    运算问题:

    % 取余

    \\ 整除

    取余的原理

    print(10 % 3)   #输出结果 1
    print(10 % -3)  # 输出结果 -2

    整除的原理:结果向下取整

    .进制转换

    进制也就是进制位,我们常用的进制包括:二进制、八进制、十进制与十六进制,它们之间区别在于数运算时是逢几进一位。比如二进制是逢2进一位,十进制也就是我们常用的0-9是逢10进一位,16进制的10-15用A、B、C、D、E、F来表示。

    1. 十进制转二进制

    方法为:十进制数除2取余法,即十进制数除2,余数为权位上的数,得到的商值继续除2,依此步骤继续向下运算直到商为0为止。

    2. 二进制转十进制

    方法为:把二进制数按权展开、相加即得十进制数。

    第一个的1*2的7次方,是因为数位就是8位,8-1=7,依此类推。

    #十进制转二进制
    print(bin(175))  #0b10101111
    
    #十进制转八进制
    print(oct(175))  #0o257
    
    #十进制转16进制
    print(hex(175))  #0xaf

    . 数据类型

    Python有五个标准的数据类型:

    Numbers(数字) V = 1 int类

    Boolean value(布尔值) V = True (bool类)

    String(字符串) V = “Good” (str类)

    List(列表) V = [“good”,”best”] (list类)

    Tuple(元组) V = (“good”,”best”) (tuple类)

    Dictionary(字典) V = {“name”:”zrh”,”age”:20} (dict类)

    字符类型的相互转换

    1.int类(记住一个)

    bit_length()表示当前十进制数用二进制数表示时,最少使用的位数。

    代码示例:

    count = 16
    v = count.bit_length()
    print(v,"---",count)

    输出结果:

    5 --- 16

    注意: 

    count = "1"
    count1 = "2"
    print(count+count1)  #输出结果:12    字符串的加法是拼接的作用
    count2 = 1
    count3 = 2
    print(count2+count3)  #输出结果:3   数字的加法是加法作用
    #需求,输入一个数字,然后每个数字相加,列入输入152,结果就是1+5+2
    count4 = "152"  #在数字和字符串中只有字符串才可以遍历,所以要把count4转为str类型
    val = 0
    for i in range(len(count4)):    
        val += int(count4[i])   #count4[i]是字符串,所以要转为数字才能相加
    print(val) 

    浮点数:

    2.str类

    对于字符串,执行内置命令后,原来的值不变。

    2.1:upper()转换字符串中的小写字母为大写

    代码示例:

    name = "zrh"
    v = name.upper()
    print(v,"---",name)

    输出结果:

    ZRH --- zrh

    2.2:lower()转换字符串中所有大写字符为小写

    代码示例:

    name = "ZrH"
    v = name.lower()
    print(v,"---",name)

    输出结果:

    zrh --- ZrH

    2.3:capitalize()将字符串的第一个字符转换为大写

    代码示例:

    name = "zrh"
    v = name.capitalize()
    print(v,"---",name)

    输出结果:

    Zrh --- zrh

    2.4:strip()去除首尾的内容 空格、换行符、制表符、指定内容

    代码示例:

    name = " zrh "
    v = name.strip()
    print(v+"---",name)

    输出结果:

    zrh---  zrh

    name_1 = "\tzrh\t"
    print(name_1)
    print(name_1.strip())

    输出结果:

    (    zrh    )空格是\t的结果

    (zrh)

    name_1 = "zrh"
    print(name_1)
    print(name_1.strip("h"))

    输出结果:

    zrh

    zr

    2.5:lstrip()截掉字符串左边的空格或指定字符

    2.6:rstrip()删除字符串字符串末尾的空格

    2.7:replace(str1, str2 , max)将字符串中的 str1 替换成 str2,如果max指定,则替换不超过max次

    代码示例:

    content = "人生自古谁无死,早死晚死都得死"
    v = content.replace("","*",2)
    print(v,"---",content)

    输出结果:

    人生自古谁无*,早*晚死都得死 --- 人生自古谁无死,早死晚死都得死

    2.8: len(string)返回字符串长度

    代码示例:

    content = "人生自古谁无死,早死晚死都得死"
    v = len(content)
    print(v)

    输出结果:

    15

    2.9:[]根据索引取值

    代码示例:

    #索引值从0开始计算不是从1
    content = "人生自古谁无死,早死晚死都得死"
    v = content[0]       #取字符串的第一个字符
    v1 = content[-1]     #-代表从后往前找,1代表第一个,所以-1代表正向的最后一个
    v2 = content[0:5]    #从0开始取到索引值为4的对象,不包括索引值为5的对象,相当于数学中的左闭右开区间
    v3 = content[8:]     #从索引值为8的对象开始取到最后一个
    v4 = content[0:15:2]  #从0开始隔一个取一个,一直取到14,2表步长表示隔一个取一个,3就表示隔2个
    print(v,v1,v2,v3,v4)

    输出结果:

    人 死 人生自古谁 早死晚死都得死 人自谁死早晚都死

    2.10 :split(“str”,num)  ()里没有参数的话,默认是空格

    以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串

    代码示例:

    content = "人生自古谁无死,早死晚死都得死"
    v = content.split("",2)
    print(v)

    输出结果:

    ['人生自古谁无', ',早', '晚死都得死']

    2.11 :.isdecimal()判断当前字符串中是否全部都是数字

    代码示例:

    v = "a123"
    c = v.isdecimal()
    print(c)

    输出结果:

    False

    补充:

    python中isdigit()、isdecimal()和isnumeric的区别  

    a = "good 1 night 2"
    a.isdecimal()    #如果a中只有十进制字符,则返回True,否则为False
    a.isdigit()      #如果a中的所有字符都是数字,并且在S中至少有一个字符,则返回True
    a.isnumeric()    #如果a中只有数字字符,则返回True,否则为False

    2.12 :join(seq) 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串

    seq里的元素必须是字符串,不能是数字,数字和字符串(前面的“_”)不能相加,

    代码示例:

    list1 = ['alex','zrh','sdv']
    a = '_'.join(list1)             #这里的_就表示用_连接
    b = "".join(list1)              #""里什么都没有表示直接连接
    print(a)
    print(b)

    输出结果:

    alex_zrh_sdv

    alexzrhsdv

    2.13:把字符串转换成字节encode()

    name = "天下"
    name.encode("utf-8")   #把字符串(Unicode)转换成字节(utf-8格式)
    name.encode("gbk")     #把字符串(Unicode)转换成字节(gbk格式)

     2.14:count() 

    count() 方法用于统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置。

    name = "ooxxooxxooxx"
    print(name.count("o"))
    #有两个参数,不写默认为print(name.count("o",0,len(name)))
    #0表示条件统计起始索引值,len(name)表示终止索引值

    2.15:expandtabs() 方法把字符串中的 ('\t')转为空格,('\t')默认的空格数是 8,\t 表示横向制表符  \n表示换行符

    name = "ID\tname\tpasswd\n1\tzrh1\t123\n2\tzrh2\t123"
    val = name.expandtabs(20)   #20表示连同\t前面的内容一共占20个字符的位置
    print(val)

    输出结果:

    2.16其他不常用的方法汇总:

    五.格式转换

    1.数字转字符串 str(对象)

    2.字符串转数字 int(对象)

    对象必须是形为数字,才能转换

    Int(string)就会报错

    3.数字转布尔值 bool(对象)

    bool(0)是False

    其他不是0的数都是True

    但是在其他方面true = 1 flase = 0

    4.字符串转布尔值 bool(对象)

    bool(“”)是False

    其他任何字符串都是True

    代码示例:

    a = 9 or 2>3
    print(a)

    输出结果:9

    代码示例:

    a = 0 or 2>3
    print(a)

    输出结果:False

    代码示例:

    a = 0 or 6
    print(a)

    输出结果:6

    代码示例:

    a = 0 or 2<3
    print(a)

    输出结果:True

    5.元组转列表

    v = (1,2,3)
    val = list(v)

    6.列表转元组

    v = [1,2,3]
    val = tuple(v)

    7.列表转字符串

    v = ["1","2","3"]
    result = "".join(v)
    print(result)

    六、For循环

    Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串。

    for循环的一般格式如下:

    for 变量接收名 in 对象 :

    代码示例:

    list1 = ["one","two","three",4]
    for i in list1:
      print(i)

    输出结果:

    one

    two

    three

    4

    For循环时加上序号enumerate:

    list1 = ["手机","电脑","ipad"]
    for i,v in enumerate(list1,1):     #表示遍历list1这个列表,序号从1开始。
      print(i,v)

    输出结果:

    1 手机

    2 电脑

    3 ipad

    循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行,简而言之就是break后不会执行下级的else(注意break的级别)

    range()函数

    如果你需要遍历数字序列,可以使用内置range()函数,它会生成数列

    range(起始值,终止值,步长)这里是左闭右开区间,可以取到起始值,但是取不到终止值,只能取到终止值的前一个,步长就是遍历时的距离,默认是1

    代码示例:

    for i in range(5,1,-1):
      print(i)

    输出结果:

    5

    4

    3

    2

    range的组和用法:

    可以结合range()和len()函数以遍历一个序列的索引:

    list1 = ["手机","电脑","ipad"]
    for i in range(len(list1)):      #len是从1开始,range没写参数是从0开始
      print(i,list1[i])

    输出结果:

    0 手机

    1 电脑

    2 ipad

    print中的自动换行

    print 会自动在行末加上回车, 如果不需回车,只需在 print 语句的结尾添加一个逗号 , 并设置分隔符参数 end,就可以改变它的行为。

     

    七、三元运算

    a = 1
    b = 2
    if a < b :
        c = b
    else:
        c = a

    这样写代码非常繁琐,所以在遇到if else非常简单的时候,可以用到三元运算

    a = 1
    b = 2
    c = b if a < b else a

     ①---⑥表示写三元运算时候的流程

    八.列表

    列表是Python中最基本的数据结构。列表中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。

    创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。

    如下所示:

    list = ["one","two",3,4,"five"]

    列表可以进行 增、删、改、查。如果列表只有一个对象,在后面也要加上,

    列表中的元素可以是 数字、字符串、布尔值、列表(列表的嵌套)

    复制列表:

    a = [1,2,3]
    b = a[:]      #[:]是复制列表
    print(a,b)     

    1.切片:

    list[1:]      #从1开始取到最后 
    list[1:-1]    #从1开始取到倒数第二值
    list[1:-1:1]   #从左到右一个一个去取,取到倒数第二值
    list[1::2]     #左到右隔一个去取
    list[3::-1]     #从3开始从右到左一个一个取,注意索引值不变

    切片器详解:

    str[a:b:c]

    a表示切片开始的索引位置

    b表示切片结束的索引位置

    a,b参数都可正可负

    a,b为正数的时候,左边第一个内容索引为0

    a,b为负数的时候,右边第一个内容索引为1

    参数c表示从左到右(c=1)或者从右到左(c=-1)

    str = 'onetwothree'
    #打印字符串倒数后两位的值
    val = str[-1:-3:-1]
    print(val)   #打印结果:ee

    2.增  添加:

    2.1:append()

    append(“str”)将数据插到最后一个位置

    代码示例:

    list = ["one","two",3,4,"five"]
    list.append("six")
    print(list)

    输出结果:

    ['one', 'two', 3, 4, 'five', 'six']

    append()注意事项:

    1 list1 = [11,22,33]
    2 val = list1.append(44)
    3 print(val)
    4 #这里返回的是None,对于列表来说,执行方法之后改变的是原来的值,变量接收不到

    2.2:insert()

    根据索引值位置将数据插入到任意一个位置

    代码示例:

    list = ["one","two",3,4,"five"]
    list.insert(2,"two2")     #想把新对象插在什么位置就输入相应的索引值
    print(list)

    输出结果:

    ['one', 'two', 'two2', 3, 4, 'five']

    3.改  修改:

    想要修改首先得用切片把相应的值取出来,在进行赋值即可。

    代码示例:

    list = ["one","two",3,4,"five"]
    list[1] = 2   #将索引值为1的对象取出来,再重新赋值
    print(list)

    输出结果:

    ['one', 2, 3, 4, 'five']

    需求:将list = ["one","two",3,4,"five"]这个列表里的two 和 4 修改成 2 和 four

    代码示例:

    list = ["one","two",3,4,"five"]
    list[1:4:2] = [2,"four"]
    print(list)

    输出结果:

    ['one', 2, 3, 'four', 'five']

    注意:在list[1:4:2] = [2,"four"]中,因为list[1:4:2]输出得是一个列表,所以等号右边也必须是个列表

    4.删除:

    4.1:remove

    remove只能删除一个,并且()里填写的是对象内容

    代码示例:

    list = ["one","two",3,4,"five"]
    list.remove("two")     #删除two
    print(list)

    输出结果:

    ['one', 3, 4, 'five']

    4.2 :pop 

    pop删除的时候()里是填写索引值,并且还可以将删除数据返回出来,如果括号里面不填索引值,即pop(),则默认删除最后一个值。

    代码示例:

    list = ["one","two",3,4,"five"]
    a = list.pop(1)    #删除 two
    print(list,a)

    输出结果:

    ['one', 3, 4, 'five'] two

    4.3 :del什么都可以删除

    代码示例:

    list = ["one","two",3,4,"five"]
    del list[0]    #删除 one
    print(list)

    输出结果:

    ['two', 3, 4, 'five']

    5.列表的其他操作

    5.1 :count:计算某元素出现次数

    代码示例:

    list = ["one","two",3,4,"five"]
    v = list.count("two")   #计算two出现的次数
    print(v)

    输出结果:1

    5.2:extend:用于在列表末尾一次性追加另一个序列中的多个值,括号中必须是可迭代对象,可以理解为批量的append()

    代码示例:

    a = [1,2,3]
    b = [4,5,6]
    a.extend(b)     #把b加到a里面
    print(a)
    print(b)

    输出结果:

    [1, 2, 3, 4, 5, 6]

    [4, 5, 6]

    5.3:index根据内容找位置,输出得是第一个匹配内容的索引位置

    代码示例:

    list = ["one","two",3,4,"five"]
    T = list.index("five")      #查找five的索引值
    print(T)

    输出结果:4

    5.4 合集

    1.reverse:用于反向列表中元素

    2.sort:对原列表进行排序

    reverse -- 排序规则,reverse = True 降序(由大到小), reverse = False 升序(由小到大)(默认)

    3.in:查一个数据在不在列表内

    4.type:身份判断:判断一个对象是不是列表

    代码示例:

    list0 = ["one","two",str(3),str(4),"five"]
    list0.reverse()             #反向列表中元素
    print(list0)
    list0.sort(reverse=True)    #由大到小de对原列表进行排序
    print(list0)
    a = "six" in list0         #判单six在不在列表里
    print(a)
    b = type(list0) is list     #判断list0是不是列表
    print(b)

    输出结果:

    ['five', '4', '3', 'two', 'one']

    ['two', 'one', 'five', '4', '3']

    False

    True

    6.列表练习题:

    list = ["one","two",3,4,"five","天才"]

    把list列表中的天才的 天 改成 蠢

    代码示例:

    list = ["one","two",3,4,"five","天才"]
    v = list[5].replace("","")
    list[5] = v
    print(list)

    输出结果:['one', 'two', 3, 4, 'five', '蠢才']

    注意:字符串不能通过索引值修改,只能通过索引值取出来。(⬇)

    7.补充:

    需求:索引为奇数值,删除
    注意:删除列表元素时,会影响列表长度,从而使得索引取值时,容易出现错误。

    li = [11,22,33,44,66]
    # 解决方案一:
    li = [11, 22, 33, 44, 66] # 0
    new_list = []
    for i in range(0,len(li)):
        if i%2 == 0:
            new_list.append(li[i])
    li = new_list
    print(li)
    
    # 解决方案二:
     li = [11, 22, 33, 44, 66] # 0
     for i in range(len(li)-1,-1,-1): # 4,0
        if i%2 == 1:
            del li[i]
    print(li)
    
    #解决方案三:切片+步长
    li = [11, 22, 33, 44, 66] 
    del li[0:4:2]
    print(li)   

    九、列表推导式

    需求:将[1,3,5]中的每个元素平方

    正常思路:

    new_list = []
    for i in [1,3,5]:
        new_list.append(i*i)
    print(new_list)  #输出结果:[1, 9, 25]

    列表推导式:以[ ]框住里面的内容

    print([i*i for i in [1,3,5]])  #输出结果:[1, 9, 25]

    列表推导式图示流程:

    可以看出列表推导式的作用就是简化代码

    列表推导式例题:

    1.输出10以内能被三整除的数的平方

    print([i*i for i in range(10) if i %3 == 0])  #[0, 9, 36, 81]

    2.输出列表每一个包含‘o’元素的字符串

    list_case = [['one','two','three'],['four','five','six']]

    正常思路:

    list_case = [['one','two','three'],['four','five','six']]
    for i in list_case:
        for v in i:
            if v.count('o')>0:
                print(v)

    列表推导式:

    list_case = [['one','two','three'],['four','five','six']]
    print([v for i in list_case for v in i if v.count('o')>0])

    十、元组

    Python 的元组与列表类似,不同之处在于元组的元素不能修改。

    元组使用小括号,列表使用方括号。

    元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

    1. 创建空元组

    tup1 = ()

    2. 元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用:

    代码示例:

    tup1 = (50)
    print(type(tup1))     # 不加逗号,类型为整型
    tup1 = (50,)
    print(type(tup1))     # 加上逗号,类型为元组

    输出结果:<class 'int'>、<class 'tuple'>

    3. 元组可以使用下标索引来访问元组中的值

    4. 可以对元组进行连接组合

    5.元组可以计算长度len()

    6.元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组

    7.重点:

    元组的儿子不能修改,但是孙子可以,元组的元素不能修改,但如果元组的元素不是元组类型的话,那么元组的元素的元素是可以修改的。

    代码示例:

    tuple1 = ("one","two","three",[1,2,"zrh"],(1,2,3),"four")
    tuple1[3][1] = 3
    print(tuple1)
    tuple1[3].append("q")
    print(tuple1)

    输出结果:

    ('one', 'two', 'three', [1, 3, 'zrh'], (1, 2, 3), 'four')

    ('one', 'two', 'three', [1, 3, 'zrh', 'q'], (1, 2, 3), 'four')

    十一、字典

    字典是另一种可变容器模型,且可存储任意类型对象。

    字典的每个键值(key=>value)对,用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中

    键必须是唯一的,但值则不必。

    值可以取任何数据类型,但键必须是不可变类型。

    不可变类型:整型、字符串、元组

    可变类型:字典、列表

    格式:变量名 = {键:值,键:值}

    代码示例:

    dict1 = {
        "name":"zrh",
        "age":20,
        "height":75
    }

    1.:dict.get

    1.1通过键取值

    代码示例:

    dict1 = {
        "name":"zrh",
        "age":20,
        "height":75
    }
    print(dict1.get("name"))

    输出结果:zrh

    1.2()参数,如果键不存在,就用后面的结果当作默认值。

    代码示例:

    dict1 = {
        "name":"zrh",
        "age":20,
        "height":75
    }
    print(dict1.get("key",999))

    输出结果:999

    2.:dict.keys() 、 dict.values() and dict.items()

    经常和for循环一起使用

    字典在for循环的时候尽量不要用两个变量去分别接收 键 和 值,这样会造成内存负荷过大,可以先遍历键,然后通过键去找值

    代码示例:

    dict1 = {
        "name":"zrh",
        "age":20,
        "height":75
    }
    a = dict1.keys()         #查看所有键
    print(type(a))           #查看a的类型
    print(a)
    print(dict1.values())    #查看所有值
    print(dict1.items())     #查看所有键值对

    输出结果:

    <class 'dict_keys'>

    dict_keys(['name', 'age', 'height'])

    dict_values(['zrh', 20, 75])

    dict_items([('name', 'zrh'), ('age', 20), ('height', 75)])

    for循环注意事项:

    dict1 = {}
    for key in dict1:
        pass
    for key in dict1.items():
        pass
    for key in dict1.keys():
        pass
    for key in dict1.values():
        pass

    注意dict1后面括号的有无

    3.增加键值对

    代码示例:

    dict1 = {
        "name":"zrh",
        "age":20,
        "height":75
    }
    dict1["hobby"] = "eat"
    print(dict1)

    输出结果:{'name': 'zrh', 'age': 20, 'height': 75, 'hobby': 'eat'}

    如果增加的键已经存在,那就是改的功能。

    4.删除

    代码示例:

    dict1 = {
        "name":"zrh",
        "age":20,
        "height":75
    }
    del dict1["name"]     #删除指定键值对
    print(dict1)
    dict1.clear()
    print(dict1)         #清空字典中所有键值对,但空字典还存在
    dict2 = {
        "name":"zrh",
        "age":20,
        "height":75
    }
    a = dict2.pop("name")    #通过键去删除,并可以返回相应的值
    print(a)
    print(dict2)
    b = dict2.popitem()
    print(b)
    print(dict2)            #随机删除一对键值对,并且返回相相应键值对

    输出结果:

    {'age': 20, 'height': 75}

    {}

    zrh

    {'age': 20, 'height': 75}

    ('height', 75)

    {'age': 20}

    5.嵌套

    字典里面可嵌套字典或者列表都可以,列表页都可以嵌套字典。

    在修改时,遇到字典用键,遇到列表用索引值,然后查找出来之后赋值即可,其他操作一样,反正一句话:

    遇到字典用键,遇到列表用索引值。

    6.update()用于将括号中的键值对添加到目标对象中,如果括号中的键在目标对象中存在,则更新目标对象的值

    1 dict1 = {
    2     'k1':'v1',
    3     'k2':'v2',
    4     'k3':'v3'
    5 }
    6 dict1.update({'k4':'v4','k1':'v11'})
    7 print(dict1)
    8 #输出结果:{'k1': 'v11', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}

    7.fromkeys()创建字典

     1 #fromkeys使用的时候不是文件名.  是用dict.来调用
     2 val = dict.fromkeys(['k1','k2','k3'],666)   #将666作为值赋给K1 K2 K3三个键
     3 print(val)          #输出结果{'k1': 666, 'k2': 666, 'k3': 666}
     4 val['k1'] = 999     #给数字重新赋值,在内存中重新开辟一块内存用来储存999,然后k1指向999,原来的k2 k3值不变
     5 print(val)         #输出结果{'k1': 999, 'k2': 666, 'k3': 666}
     6 
     7 val = dict.fromkeys(['k1','k2','k3'],[])
     8 val['k1'].append(666)
     9 val['k2'].append(999)
    10 #k1 k2 k3指向的是同一个值,即[],每次往里加内容的时候 k1  k2  k3 的值都会发生变化
    11 print(val)   #输出结果{'k1': [666, 999], 'k2': [666, 999], 'k3': [666, 999]}
    12 
    13 val = dict.fromkeys(['k1','k2','k3'],[])
    14 val['k1'].append(666) 
    15 val['k1'] = [1,2,3]  #这里是重新赋值操作,在内存中重新开辟一块空间储存[1,2,3],k1指向他,k2 k3值不变
    16 print(val)  #输出结果{'k1': [1, 2, 3], 'k2': [666], 'k3': [666]}

    8.补充

    # 题:dic = {'k1':"v1",'k2':'v2'}把key="k1",键值对删除
    del dic['k1']
    # 题:dic = {'u1':"v1",'k2':'v2','k3':'v3'}把key中存在k,键值对删除
    dic = {'u1':"v1",'k2':'v2','k3':'v3'}
    # 不要在循环当前字典的过程中,修改当前字典大小
    错误方式:
    for key in dic:
        if 'k' in key:
            del dic[key]
    正确方式 :
    dic_key_list = []
    for key in dic:
        dic_key_list.append(key)
    for row in dic_key_list:
        if 'k' in row:
            del dic[row]
    print(dic)    

    十二、集合set

    集合(set)是一个无序的不重复元素序列。

    可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

    1 list1 = [] #等价于list1 = list()
    2 tuple1 = () #等价于tuple1 = tuple()
    3 dict1 = {}  #等价于dict1 = dict()
    4 #所以创建集合是 set()

    集合里的元素必须是不可变的

    set1 = {“1”,“zrh”,[1,2,3]}这样就会报错,因为列表是可变的

    不可变类型:整型、字符串、元组

    可变类型:字典、列表

    集合也可以for循环,集合不可以通过索引来取值,因为集合无序。

    创建格式:

    1 parame1 = {"one","two","three"}    #创建方法1
    2 a = set("apple")     #创建方法2
    3 print(parame1,a)
    4 #打印结果{'two', 'three', 'one'}集合无序的; 
    5 #{'l', 'p', 'a', 'e'}因为是不能重复的,所以只有一个a

    Set内置方法:

    方法

    描述

    add()

    为集合添加元素(无返回值)

    clear()

    移除集合中的所有元素(无返回值)

    copy()

    拷贝一个集合(无返回值)

    difference()

    返回多个集合的差集(返回一个新的集合)

    difference_update()

    方法用于移除两个集合中都存在的元素(无返回值)

    discard()

    删除集合中指定的元素(无返回值)删除元素不存在不会报错

    intersection()

    返回集合的交集(返回一个新的集合)

    intersection_update()

    更新指定集合为指定集合和参数集合的交集(无返回值)

    isdisjoint()

    判断两个集合是否无交集,如果没有返回 True,否则返回 False(返回布尔值 )

    issubset()

    判断指定集合是否为该方法参数集合的子集(返回布尔值 )

    issuperset()

    判断该方法的参数集合是否为指定集合的子集(返回布尔值 )

    pop()

    随机移除元素(返回移除的元素)

    remove()

    移除指定元素(返回移除的元素)删除的元素不存在会报错

    symmetric_difference()

    返回两个集合中不重复的元素集合(返回一个新的集合)

    symmetric_difference_update()

    移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中(无返回值)

    union()

    返回两个集合的并集(返回一个新的集合)

    update()

    给集合添加元素(无返回值)

     

    Set内置方法部分应用举例:

    #1.add() 添加  参数必须是字符串
    name = {'one','two','three','four','five'}
    a = name.add('six')  #括号内的元素只能填一个,并且要维护集合元素永不重复
    print(a)       #输出结果:None 说明add不可返回值,直接修改的是集合
    print(name)   #输出结果:{'four', 'five', 'three', 'six', 'one', 'two'}
    #2.update() 添加更新  参数可以是列表,元组,字典,集合等
    name = {'one','two','three','four','five'}
    a = name.update(['six','seven'])
    print(a)       #输出结果:None 说明update不可返回值,直接修改的是集合
    print(name)   #输出结果:{'three', 'seven', 'four', 'six', 'one', 'two', 'five'}
    #3. difference()  用于计算差集
    #difference() 方法用于返回集合的差集,即返回的集合元素包含在第一个集合中,但不包含在第二个#集合(方法的参数)中。
    name = {'one','two','three','four','five'}
    name1 = {'five','six','seven'}
    a = name.difference(name1)   #name中存在,name1中不存在,创建新变量,name name1值不变
    print(a)       #输出结果:{'three', 'four', 'one', 'two'}
    #4. difference_update() 方法用于移除两个集合中都存在的元素。
    #difference_update() 方法与 difference() 方法的区别在于 difference() 方法返回一个移除相同元素的新集合,
    而 difference_update() 方法是直接在原来的集合中移除元素,没有返回值。
    name = {'one','two','three','four','five'}
    name1 = {'five','six','seven'}
    a = name.difference_update(name1)   #在name中删除name1中存在的值
    print(a)       #输出结果:None 没有返回值
    print(name)   #输出结果:{'four', 'two', 'three', 'one'}
    快速去重:利用集合元素不重复的方法
    name = ['one','two','five','three','four','five']
    val = set(name)  #将列表转换为集合格式
    print(val)   #{'four', 'two', 'five', 'one', 'three'}

    set集合也可以进行> < 的比较:

    #判断b是不是a集合的子集
    a = {1,2,3,4,5}
    b = {4,5}
    print(a>b)
    # 结果为True
    
    a = {1,2,3,4,5}
    b = {1,2,3,4,5}
    print(a1!=b) !=不等于的意思
    #结果为False,代表a,b两个集合相同

    十三、文件操作

    文件操作三要素

    1. 路径:D:\\name.txt

    2. 编码:utf-8或gbk等

    3. 模式:

    x

    写模式,新建一个文件,如果该文件已存在则会报错。

    b

    二进制模式。即bytes

    +

    打开一个文件进行更新(可读可写)

    r

    以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。

    rb

    以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。

    r+

    打开一个文件用于读写。文件指针将会放在文件的开头。常用

    rb+

    以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。

    w

    打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。

    wb

    以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。

    w+

    打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。

    wb+

    以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。

    a

    打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。

    ab

    以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。

    a+

    打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。

    ab+

    以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

    1.只读模式r:

    obj = open('D:\\name.txt',encoding='utf-8',mode='r')  #\\中的第一个\表示转义符
    #            文件路径        编码格式        模式
    content = obj.read() #此时的content是str类型,str在内存上又是Unicode类型
    # 所以mode = 'r' python内部会把utf-8数据转换成Unicode类型
    obj.close()
    obj = open('D:\\name.txt',mode='rb')
    #          文件路径    模式
    content = obj.read() #此时的content是bytes类型,打印出来是bytes的表现形式
    obj.close()

    总结:

    1.文件在硬盘上存储一定是UTF-8或者GBK等编码的01

    2.rb=原封不动的拿数据,数据此时是某种编码的01,为了显示方便,便会显示bytes的表现形式

    3.r=内部会有转换,但是必须记住要加编码格式encoding = ‘utf-8’等

    4.encoding是文件之前用什么编码保存,就用什么编码打开

    5.一般情况下mode = ‘rb’,用bytes的很少,一般用于上传,下载文件时才用到

    只写模式w:

    写之前会清空里面的内容再写

    1.open(文件路径,mode='wb')

    count = open('name.txt',mode='wb')
    count.write("dooble".encode('utf-8'))  
    #wb模式下,往里存的必须是utf-8等编码格式,字符串默认是Unicode,所以要转换成utf-8
    count.close()

    2.open(文件路径,mode='w',encoding='utf-8')

    count = open('name.txt',encoding='utf-8',mode='w')
    count.write('123')        #会先清空,再写,只能写不能读
    count.close()

    3.writelines()  将列表的内容写入文件,参数是个列表

    只追加模式a:

    追加模式不清空原来文件的内容

    1.open(文件路径,mode='ab')

    count = open('name.txt',mode='a',encoding='utf-8')
    count.write("name1")  
    count.close()

    2.open(文件路径,mode='a',encoding='utf-8')

    count = open('name.txt',mode='ab')
    count.write("name1".encode('utf-8'))  
    #ab模式下,往里存的必须是utf-8等编码格式,字符串默认是Unicode,所以要转换成utf-8
    count.close()

    r+模式:

    count = open('name.txt',mode='r+',encoding='utf-8') #r+可读可写 w+可写可读,写之前会清空原文件内容,读的是你写的内容
    #此时指针在第一个位置,不跳指针继续写会从第一个位置覆盖
    count.write("name1")  #这样就直接覆盖了
    count.read() #读到最后,指针此时在最后了
    count.write("name1")   #指针在最后,于是就添加到最后了
    #要想在第二个位置覆盖,那需要调整指针
    count.seek(0) #将指针调整到0位置
    count.write("2")  #此时2就覆盖了原来在0位置的内容
    count.close()  #关闭文件

    r+模式注意事项:

    file文件内容:

     注意事项一:

    with open("file",'r+',encoding='utf-8') as file_1:  #打开文件时候不清空文件
    file_1.readline()        #读第一行,指针现在在第一行末尾
    file_1.write("good")     #在执行写操作的时候,是在文件末尾追加

    输出结果:

    注意事项二:

    当不执行读操作的时候,再写的话默认从开始的位置覆盖

    with open("file",'r+',encoding='utf-8') as file_1:  #打开文件时候不清空文件
        file_1.write("good")    #当不执行读操作的时候,再写的话默认从开始的位置覆盖

    输出结果:

    所以在以后的操作中,不要同时读写操作一个文件,因为会乱,所以不用“R+”,就单独的用 r、w、a

    文件的功能:

    read

    obj = open('美女.txt',mode='r+',encoding='utf-8')
    data = obj.read()  # 读取所有文件内容
    data = obj.read(2) # 在r模式中读取的2是2个字符;在rb模式中读取的2是2个字节
    obj.write('字节或字符串')

    seek

    obj = open('美女.txt',mode='r+',encoding='utf-8') #打开文件时注意该文件是不是用utf-8编码的
    obj.seek(2)         # 参数2永远是字节,用来指定指针的位置 utf-8一个中文3个字节

     tell等

    obj.tell()          # 读取当前指针的位置,读取到的是字节数
    obj.writable()   #是否可写,r模式下就不可写,可以用变量接收返回值
    obj.readable()   #是否可读,w模式下就不可读,可以用变量接收返回值

    flush将内存中内容刷到硬盘

    count = open('name.txt',mode='r+',encoding='utf-8')
    while True:
        val = input(">>>")
        count.write(val)    #给文件里写内容
        count.flush()       #强行把内容刷到硬盘,不然文件在循环里永远关闭不了
    count.close()

    readline()从文本文件中读取一行内容作为结果返回,结果为字符串类型

    file_name文件内容:

    with open('file_name','r',encoding='utf-8') as file:
        val = file.readline()
        print(type(val))
        print(val)
        # 在读第二行的时候,第一行内容是 君不见黄河之水天上来\n,其中的\n也会被读出来,所以打印的时候中间会多一行间隙
        val = file.readline()
        print(val)

    输出结果:

    readline常用的一种方法:

    with open('file_name','r',encoding='utf-8') as file:
        for line in file:
            print(line)  ##即使文件有80个G,for循环的垃圾回收体制会即时节省内存

    readlines()将文本文件中的每行文本作为一个字符串存入列表中,返回该列表,对于大文件会占很多内存,不建议使用

    truncate()

    obj.truncate()  #截取文件内容,根据指针位置,只保留指针之前数据

    注意:写文件的时候一定记着关闭文件,这里有一种自动关闭的方法:

    with open("name.txt",mode="r+",encoding="utf-8") as count:   #as 后面是接收打开文件对象的变量名
        #在缩进里写代码内容
    #等待运行完代码后会自动跳出缩进,就自动关闭了

    总结:

    with open("file",'r+',encoding='utf-8') as file_1: #打开文件时候不清空文件
       pass
    import os
    os.remove('file')   #删除file的文件
    os.rename('file','file_new')  #将文件名file修改为file_new

    文件内容的修改:

    步骤:

    1.先遍历文件

    2.str.replace或者str.split

    3.将修改后的所有文件重新写入一个新文件

    4.删除原来文件

    5.将新文件重命名为原来文件的名字

    举例:

    file文件的内容:

    需求1:给每一项的第一个 | 前的字母加上  _good

    import os   #导入os模块
    file_2 = open("file_new",'w',encoding='utf-8')   #以写模式打开file_new文件(无此文件则会创建),打开之前会清空原文件内容
    with open("file",'r',encoding='utf-8') as file_1:  #以读模式打开file文件
        for line in file_1:         
            list_1 = line.split("|")     
            list_1[0] = list_1[0]+"_good"
            content = '|'.join(list_1) 
            file_2.write(content)           #每遍历一个内容,修改后就写到file_new里面
    file_2.close()
    os.remove('file')     #删除原来的file文件
    os.rename('file_new','file')  #将file_new文件重命名为file

    输出结果:

    需求2:给zcx后面加上 _good ,其他保持不变

    import os   #导入os模块
    file_2 = open("file_new",'w',encoding='utf-8')   #以写模式打开file_new文件(无此文件则会创建),打开之前会清空原文件内容
    with open("file",'r',encoding='utf-8') as file_1:  #以读模式打开file文件
        for line in file_1:
            list_1 = line.split("|")
            if list_1[0] == 'zcx':    #判断是不是zcx
                list_1[0] = list_1[0]+"_good"
            content = '|'.join(list_1)
            file_2.write(content)           #每遍历一个内容,修改后就写到file_new里面
    file_2.close()
    os.remove('file')     #删除原来的file文件
    os.rename('file_new','file')  #将file_new文件重命名为file

    输出结果:

    Json文件解析:

    Json本质上是—种嵌套字典格式,但键所对应的值,往往更加复杂,不仅是数字,还可以是字符串,数组,列表等

    import json
    with open('F:\pycharm\data\case.json',mode='r',encoding='utf-8-sig') as file:
        file_case = file.read()
        print(type(file_case))   #<class 'str'>
        data = json.loads(file_case)  #将file_case文件解析成json格式,参数的对应的文件内容必须是字符串格式
        print(type(data))  #<class 'dict'>
        print(data)
    with open('F:\pycharm\data\case_write.json',mode='w',encoding='utf-8') as filr:
        json.dump(data,filr,indent=0)  #将data数据写入到filr对应的json文件里,indent=0表示空格为0

    十四、变量指向和深浅拷贝

    1.变量指向:

    name = "zrh"
    name1 = name
    print(name,name1)
    name = "zrh1"
    print(name,name1)
    #输出结果
    #zrh zrh
    #zrh1 zrh

    内部原理:

    name1通过name指向zrh,此时name1的值就是zrh后面即使name改变为zrh1,name1的值也不会改变。

    2.列表指向:

    list1 = [1,2,3]
    list2 = list1
    list1.append(4)
    print(list1,list2)
    #输出结果:[1, 2, 3, 4] [1, 2, 3, 4]

    内部原理:

    list2通过list1指向【1,2,3】,此时list2的值就是【1,2,3】,append直接改变的是值,所以list1和list2都改变了。

    3.深浅拷贝

    浅拷贝:只拷贝第一层,其他都指向同一数据

    深拷贝:不管里面有多少嵌套,都会拷贝下来

    深浅拷贝只有存在嵌套时才会有异同

    内存原理:

    公式格式:

    list1 = [1,[2,3],4]
    #浅拷贝
    list2 = list1.copy()
    #深拷贝
    import copy
    list3 = copy.deepcopy(list1)

    注意:

    list3最后一层是python为了节省内存才直接指向list1的数据,所以list1改变数据,是从新开辟出一块新的内存让list1指向,list3不变。

    list1 = [1,[2,3],4]
    #深拷贝
    import copy
    list3 = copy.deepcopy(list1)
    list1[0] = 0
    print(list3[0])   
    #输出结果: 1
  • 相关阅读:
    什么是动态链接库
    <<TCP/IP高效编程>>读书笔记
    C++ 函数
    我的vim配置
    FastReport4.6程序员手册_翻译
    DUnit研究初步
    ADO BUG之'无法为更新定位行....' 解决之道
    极限编程的集成测试工具Dunit
    总结
    项目管理检查清单项目启动
  • 原文地址:https://www.cnblogs.com/zrh918/p/11608667.html
Copyright © 2020-2023  润新知