• Python3 从零单排1_列表&字典&集合&字符串方法&深浅拷贝


      1.列表

      前面我们了解了str、int、float等数据类型,比如人名用str,name='大雷',那如果我们一个部门呢?还用字符串存数据么,names='大雷,云云,星星'这样存数据,在调用的时候岂不是很麻烦,比如我们想取到星星,还要用到字符串方法,会比较麻烦,或者你想每个人取一个字符串的变量名,这样也麻烦啊,有多少个人,岂不是就要顶一个多少个变量了?为了解决这些麻烦,就有了列表,顾名思义,就是一个表,里面存放一系列数据,python里的列表定义比其他语言要简单,中括弧[]括起来就是列表了,当然在python里列表也叫数组,大家不要因为名字不同而困惑,都一个概念,列表增删改查如下:

    #列表
    names=['小刚','小红','小明','小小','猛犸']    #列表命名,列表名=[元素1,元素2,元素3],元素用英文逗号隔开,元素如果是字符串需要加引号
            #0      #1      #2      #3      #4
    #列表里的元素是有排序的,所以每个元素都有一个数字编号,计算机是从0开始的,所以['小刚','小红','小明','小小','猛犸']这些元素对应的索引依次为:01234,当然在python里除了索引这个叫法,还有下标、角标,都一个意思
    
    #列表取值
    print(names[0]) #列表名[元素索引],这个格式就取到索引对应的元素了,这里取到'小刚',列表只有这一种取值方式
    print(names[-1]) #负数表示从后往前取元素,这里取到了猛犸
    
    #新增元素
    names.append('云云')  #列表名.append(元素),这个方法是在列表最后面加一个元素,这里在列表最后加上'云云'
    names.insert(2,'李白')  #列表名.insert(索引值,元素),这个方法是在指定索引位置插入元素,之前该位置及后面的额元素向后移一位,这里是在列表的第三个位置插入'李白'
    
    #修改元素
    names[0]='大刚'   #列表名[元素索引]=新元素,这样就修改元素了
    
    #删除元素
    names.pop() #默认删除最后一个元素
    names.pop(2) #删除指定下标的元素
    names.remove('小红')  #和pop不同,删除列表中指定的元素
    del names[2]    #删除指定下标的元素
    names.clear()   #清空列表
    
    #多维数组
    names1=['小刚','小红',['宙斯','火女'],'小明','小小','猛犸']    #数组里再来一个数组就是二维数组了
    names2=['小刚','小红',['宙斯',['女王','拉比克'],'火女'],'小明','小小','猛犸']    #组二维数组里再来一个数组就是三维数组了,依次类推
    print(names2[2][1][1])    #数组里面的数组就当元素来取,取出来之后,又按数组取值方式取下去就好了,这里取到了'拉比克'
    
    #enumerate  循环枚举可迭代对象的索引与值
    names=['小刚','小红','小明','小小','猛犸']
    for index,value in enumerate(names):
        print(index,value)
    # 0 小刚
    # 1 小红
    # 2 小明
    # 3 小小
    # 4 猛犸 

      列表内置方法:

     1 #内置方法:
     2 names=['小刚','小红','小明','小小','猛犸']
     3 names2=['宙斯','火女']
     4 names.extend(names2)    #合并两个list。将names2合并到names里面
     5 names+names2    #合并两个list。但和上面不一样,这里只是把两个列表连接起来,原来的列表不会变化,类似字符串相加
     6 new_name=names+names2   #用+的时候,需要用一个新列表来接收
     7 print(names.count('小小'))    #统计元素出现的次数
     8 print(names.index('小小'))    #查询到元素的索引
     9 names.reverse() #反转数组
    10 names.sort()    #数组排序,升序
    11 names.sort(reverse=True)    #数组排序,降序
    12 print(names)
    13 for index,value in enumerate(names):
    14     print(index,value)
    15 # 0 猛犸
    16 # 1 火女
    17 # 2 小红
    18 # 3 小明
    19 # 4 小小
    20 # 5 小刚
    21 # 6 宙斯

      列表切片,顾名思义,就是把列表切成我们想要的片段。上面了解到,列表是有下标、索引的,那么切片就是根据这个下标来进行切片的,比如我想去第一个元素到第三个元素,那么这样写:names[0:3],这样就取到前面三个元素了,但是你会发现,3的下标是第四个元素,为啥切片要切到3呢,因为python切片里,顾头不顾尾,意思就是从开始下标取到结束下标的前一位元素。另外如果是从0下标开始取值,那么可以省略不写,直接写[:3]即可;如果是取值到最后,那么可以省略不写最后的索引,直接写[3:]即可,显然[:]这样就是取所有的了。还有一个步长的概念,就是每走几步取一个元素,比如列表num=[1,2,3,4,5,6,7,8,9],num[0:10:2],这里就是每两个元素取一个,取的结果是:[1,3,5,7,9]。代码如下:

    1 #列表切片
    2 nums=[1,2,3,4,5,6,7,8,9]
    3 print(nums[1:3])  #取第二个元素到第三个元素,也就是2,3
    4 print(nums[3:])  #取所有的元素,一直取到最后,后面的下标可以省略不写
    5 print(nums[:6])  #取所有的元素,从头开始取,前面的下标可以不写
    6 print(nums[0:10:2])  #步长2,每两个元素取一个,这里取到1,3,5,7,9
    7 print(nums[::1])  #取所有的元素,1就是每个元素都取
    8 print(nums[::-1])  #步长为负数的情况下是从后往前取
    9 print(nums[7:1:-2])  #步长为负数时,这里的下标必须是前面的下标大于后面的下标,因为他是从后往前取的

      2.元祖

      元祖,跟列表的定义是一样的,只是元祖是用小括弧(),列表用的是中括弧[],在命名上就这一点区别,那为什么有了列表,还来一个元祖,列表就够用了啊,反正都差不多,这里是因为元祖比列表更特殊一些,元祖命名后就不能增、删、改,就已经写死了,不能动他,你只能从里面取元素,只有读取的权限。有什么用呢?像我们在开发的时候,有一些基础数据,比如数据库连接信息,这些事定死的,你改了就连接不上了,所以这里用到元祖,避免后面调试啥的误操作,增删改了数据库连接信息,导致连接失败。元祖只有三个方法(其他方法都不适用):

    #元祖
    num=(1,2,3,4,5,6,6)
    print(num[0])   #通过下标取值
    print(num.count(6)) #统计元素出现的次数
    print(num.index(6)) #查询到元素的索引

      既然说到了元祖,这里了解下可变变量和不可变变量,可变变量就是命名之后,还可以对他的内容进行增、删、改等操作,不可变变量就是,命名之后就不可以增、删、改他的内容了,像这里的元祖就是不可变变量,一旦命名就不可以对他的内容进行增、删、改等操作,只有读取的操作权限,所以元祖只有上面的三个方法,列表里的增删改都不适用于元祖,用的话会报错。类似于元祖这样的不可变变量还有字符串,字符串的内容是不可以增、删、改的,只可以读取。

       

      3.字典

      字典的概念大家再熟悉不过了,上小学就用到字典了,每天书包里都揣一字典,遇到不懂的就查一下不懂的这个关键字,然后后面跟很多解释,举例啥的。就像这个字典的需求,用列表可以实现吗?可以,但是很麻烦,比如这样存:

    words=['菜鸟','奋斗','努力']  #中文
    comments=['newbie','fight','effot'] #翻译

      如上述代码,但刚遇到这样的需求时,我们首先要找到中文words里的的下标,然后根据下标再去comments里找对应的英文,这样是可以满足字典的需求,但是词典那么多,这样找效率特别低,因为list在找元素是从前面一直找到后面,当有几万个词的时候,计算机要找很久才找的到,而且,这样存起来也不直观,看小学时候字典里那种存的多直观,前面是词,后面跟解释,所以python仿照字典弄了一个字典的样式,然后你在找词的时候,他直接找这个词,不会从前往后一个个的找,直接就找到了,他是无需的,很大程度上提高了效率。

      字典的特性:

      1.字典是无序的,因为它没有下标,用key来当索引,所以是无序的;

      2.字典的key必须是唯一的,因为它是通过key来进行索引的,所以key不能重复,所以字典里不会产生重复数据。

      字典命名也很直观,字典名={key1:value1,key2:value2},用大括号{},里面的格式是key:value,然后用逗号隔开各个元素,这样就直接定义好了一个字典并且赋值,代码如下:

     1 #字典
     2 informations={'星星':['江西',18,'',180],'大雷':['合肥',16,'',190]} #定义字典
     3 #
     4 #新增
     5 informations['人马']=['近卫',128,'未知',156]  #新增,直接指定key=value就新增了
     6 informations.setdefault('宙斯',['天灾',1280,'未知',152])  #这里的新增,如果这个key存在的话,就不修改他,不存在的话,就添加
     7 
     8 #修改
     9 informations['星星']=['湖南',22,'未知',150]  #修改,直接指定key=value就修改了,就是说如果字典存在这个key,就修改value,不存在就新增,因为字典是不能重复key的
    10 informations.update(大雷=['天灾',1280,'未知',152])    #update也可以修改,但是注意,这里的key如果是字符串的话不需要加引号
    11 
    12 #删除
    13 del informations['星星']  #删除,和list一样,list是删除指定下标的元素,这里是删除指定key的value
    14 informations.pop('人马')  #删除,和list一样,list是删除指定下标的元素,这里是删除指定key的value
    15 informations.popitem()  #随机删除一个值
    16 
    17 #查询,直接取和通过get取的区别是,当key不存在时,get方法取值不会报错,返回None;而直接取会报错,就这一个区别
    18 print(informations['人马'])   #通过key取value
    19 print(informations.get('人马'))   #用字典的get方法通过key取value
    20 
    21 #字典内置方法
    22 print(informations.keys())    #获取字典的所有key
    23 print(informations.values())    #获取字典的所有value
    24 print(list(informations.keys()))    #强制类型转换为列表
    25 print(list(informations.values()))    #强制类型转换为列表
    26 print(informations.items()) #将字典转换成一个列表,一般不这样用,字典本来就快于list,还转换成list,没必要
    27 additional={1:'a','大雷': ['火星', 16, '', 190]}
    28 informations.update(additional) #update方式是更新字典,没有的key直接新增,有可以key的话,更新value
    29 print(informations)

      可能会好奇为啥字典就比列表查询要快?可以肯定的是快太多,这里先了解一个数据类型,hash,一个函数,可以把所有不可变的对象压缩成一个特定长度的数字,好比把气体液化,缩小存储空间。基本每一个不同的对象hash后都能得到一个唯一的数字,但也存在特殊情况,可能不唯一。但是已经够我们用了,因为那种情况一般不会发生,那么hash有什么用呢?

      字典里的key就采用了hash函数来存储数据,key的定义是一个不可变对象(数字、字符串、元祖),在存储的时候(key-value),对key进行hash得到一个数字存起来,就变成了key-hash数字-value。

      我们已经学了列表,列表在查询一个值的时候,是循环列表所有元素,那么这个查询速度是很低的,复杂度是N,后面会讲到,好比你要去图书馆找一本书,那么图书馆那几十万本一本本找去,如果索引靠前还好,如果索引在最后,那么需要找几十万次才能找到。字典不一样,字典存的时候是这样的关系:key-hash数字-value,那么当你要找某个key的value时,是先把key进行hash,得到一个数字,然后根据这个数字去找value,那为什么通过数字去找value就变得很快了呢?因为字典hash过后的key可以进行排序,在一个有序的数字集合里找一个数字,可以用二分查找,算法的时候会讲,二分查找比for循环查找快的是指数级别。这样就能很快找到value了。

      字典嵌套,这个也很常用,就拿上述例子来说,首先是人名,然后是这个人的一些描述,描述内容少还好,但是,内容多的话呢,比如有身高、体重、爱好等等,太多了,用list存是不是又存在之前的问题,效率低,而且不方便取,每次取的时候还要要确定我要取得这个属性的下标然后才取得到。这里就引进了字典嵌套,用法也比较简单,如下:

    informations={
        '星星':{
            '地址':'江西',
            'age':18,
            'sex':'',
            'heights':180
        },
        '大雷':{
            '地址':'合肥',
            'age':22,
            'sex':'未知',
            'heights':190}
    }

      这样就直观很多了,不管你有多少属性,这样加下去就行了,取值方法参考字典的取值和多维数组的取值,这里不赘述了。

       

      4.集合

      集合也是数据类型,,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据,作用如下:

      1、它可以把一个列表中重复的数据去掉,而不需要你再写判断
      2、可以做关系比较,比如数学里的交集、并集等

      集合的操作和列表差不多:

    lis=[1,2,3,4,4,5,5,6,7,8,9]
    myset=set(lis)  #这就定义了一个集合
    print(myset)    #去掉了重复数据,4,5,这里只显示一次
    myset.add(888)#添加元素
    myset.update([777,666,666]) #添加值
    myset.remove(777)#删除元素,如果元素不存在会报错
    myset.pop()#删除一个随机的元素,并返回删除的元素
    myset.discard('dddd')#如果删除的元素存在,删除,不存在不做处理

      集合操作方法:

    set1 = {1, 2, 3, 4, 5, 6, 7,8,9}
    set2 = {1, 2, 3, 4, 6}
    set3 = {1, 2}
    print(set1.intersection(set2))  # 取交集,也就是取set1和set2中都有的
    print(set1 & set2)# 取交集
    print(set1.union(set2))  # 取并集,也就是把set1和set2合并了,然后去除重复的
    print(set1 | set2)# 取并集
    print(set1.difference(set2))  #取差集 在list中存在,在set2中没有的
    print(set1 - set2)
    print(set3.issubset(set1))#判断set3是不是set1的子集
    print(set3<set1)
    print(set1.issuperset(set3))#判断set1是不是set3的父集
    print(set1>set3)
    print(set1.isdisjoint(set3))#判断set1和set3是否有交集
    print(set1.symmetric_difference(set2))#对称差集,输出两个列表中都没有的值,也就是把两个集合中相同的去掉
    print(set1 ^ set2)

      5.字符串方法

      这里没什么技巧,记住这些方法就可以了,以后要用到,常用的有下面几种方法(一定要记住有这些方法,具体怎么用可以再查):

     1 #常用的字符串方法:
     2 file_name='D:1自动化day2day2笔记.txt'
     3 name='名字:{name},年龄:{age}'
     4 print(file_name.startswith('D'))  # 判断是否以x结尾
     5 print(file_name.endswith('.txt'))  # 判断是否以x结尾
     6 name.format(name='niuniu', age=18)  # 这个是格式字符串
     7 print('122'.isdigit())  # 是否是数字
     8 print(''.join(['hehe', 'haha', 'ee']))  # 拼接字符串
     9 # 1、把list转成字符串
    10 # 2、把list里面每个元素连起来
    11 print('adbefF'.lower())  # 变成小写
    12 print('adbefF'.upper())  # 变成大写
    13 print('
    mysql 
    '.strip())  #清除字符串前后空格
    14 print('mysql is db.'.replace('mysql', 'oracle'))    #替换,将字符串里所有的mysql替换成oracle
    15 print('1+2+3+4'.split('+'))  # 切割字符串,返回一个list
    16 print('1+2+3
    1+2+3+4'.splitlines())  # 按照换行符分割,返回一个list

      其他不常用字符串方法:

     1 print(name.capitalize())#首字母大写
     2 print(name.center(50,'	'))#把字符长度加到50个,如果元字符长度大于50,则字符不变,若大于50,则字符不做改变
     3 print(name.find('n'))#查找字符的索引,当查不到的时候会返回-1,
     4 print(name.index('w'))#查找字符的索引,当查不到的时候会报错
     5 print('a'.isalnum())#判断是否只包含数字或字母
     6 print('sdSD'.isalpha())#判断是否英文字母
     7 print('ads'.isidentifier())#判断是一个合法变量名
     8 print('aaa'.islower())#是否都是小写字母
     9 print('AAA'.isupper())#是否都是大写字母
    10 print('
       mysql   
    '.lstrip())#默认去掉左边的空格和换行
    11 print('
       mysql   
    '.rstrip())#默认去掉右边的空格和换行
    12 print('
       my
    sql   
    '.strip())#默认去掉左右两边的空格和换行,中间的空行去不掉
    13 print('asdfdsfsfa'.strip('a'))#去掉首尾两端的字符'a'
    14 p=str.maketrans('123','abc')#前面的字符串和后面的字符串做映射
    15 print('123'.translate(p))#输出按照上面maketrans做映射后的字符串
    16 print('asd gd gfd'.replace(' ','',1))#替换字符串,替换一次,不写数字表示全部替换
    17 print('mysql is is db'.find('is'))#返回最左边字符的下标
    18 print('mysql is is db'.rfind('is'))#返回最右边字符的下标
    19 print('AAAaaa'.swapcase())#字母大小写反转

      6.深浅拷贝&三元运算&进度条&format 格式化传字典

    # -*- coding:utf-8 -*-
    # __author__="X1gang"
    # Date:2018/11/19
    
    
    #进度条
    import time
    for i in range(10):
        time.sleep(1)
        print('*',end='',flush=True)
    # end默认参数是‘
    ’,所以没有传值的话是默认换行的;
    # flush在这里的意义是循环一次打印一次,默认参数是'False',如果指定为True,这里会10秒后一起打印10个*
    # 现在上述代码打印结果为每秒钟打印一个*
    
    # 赋值
    a=b=c='haha'
    print(id(a),id(b),id(c))    #字符串,内存地址都一样
    c='xixi'
    print(id(a),id(b),id(c))    #c内存地址不一样了
    e=f=g=['haha',123]
    print(id(e),id(f),id(g))    #列表,内存地址都一样
    g.append('xixi')
    print(id(e),id(f),id(g))    #内存地址还是都一样,也就是赋值的列表,一个列表变了,其他的表都一起变化,因为内存地址是一样的
    # 浅拷贝(字符串没有copy方法)
    lis=[1,2,3,[4,5,6]]
    clis=lis.copy()    
    print(id(lis),id(clis))    #内存地址不一样,完全复制了一份新的内存地址来存clis
    print(id(lis[-1]),id(clis[-1]))    #嵌套列表内存地址一样,也就是两个列表的嵌套列表其中一个修改内容,另一个也会跟着一起变化
    # 深拷贝(字符串也有深拷贝) 不管列表/字符串有多大,所有内容都完整的复制一份,生成新的内存地址,互不影响,一般不建议这样做,因为会占更懂的空间
    import copy
    dclis=copy.deepcopy(lis)
    print(id(lis),id(clis),id(dclis))    #内存地址不一样,完全复制了一份新的内存地址来存clis
    print(id(lis[-1]),id(clis[-1]),id(dclis[-1]))    #嵌套列表内存地址也不一样了,也就是两个列表的嵌套列表其中一个修改内容,另一个不会跟着一起变化
    
    #三元运算
    a=8
    b=2
    c=b if b>a else a   #这就是三元运算
    print(c)
    
    #format 传字典
    print('{name},{age}'.format(age=18,name='xg'))
    dic={'age':18,'name':'xg'}
    print('{name},{age}'.format_map(dic))   #format_map这个方法后面传一字典即可
    #上述输出的结果一样
    夕闻道不如朝闻道
  • 相关阅读:
    ASCII码对照表
    createPopup 超链接
    说说回车键触发表单提交的问题
    linux下配java环境的小结
    spring bind checkbox 传递值问题
    用Common validator为springMVC做验证时遇到的一个问题小记
    [转载]对android LinearLayout中layout_weight属性使用初探
    linux下tomcat启动正常,但用http://22.22.33.33:8080却访问不了,防火墙的设置问题
    Java 遍历Map时 删除元素
    ftp用户登录时不能进自己的目录,被拒绝登录的解决方法
  • 原文地址:https://www.cnblogs.com/znyyy/p/8037060.html
Copyright © 2020-2023  润新知