字符串


字符串是不可变的数据类型,不能修改,对于字符串的任何操作,都不会改变原有的字符串;

  1. # 打印字符串 (单引号 或 双引号, 三引号)
  2. s1 = 'abc'
  3. s2 = "abc"
  4. s3 = '''abc'''
  5. s4 = '''
  6. abc
  7. '''
  8. print(id(s1),id(s2),id(s3),id(s4)) # 三引号占用的内存空间与单双引号的不同(如果都写在一行上,内存地址是相同的)
  9. print(s1 == s2) # True == 比较的是内容
  10. print(s1 is s2) # True is 比较的是地址
  11. print(s2 == s3) # True
  12. print(s2 is s3) # True
  13. print(s2 == s4) # False
  14. print(s2 is s4) # False
  15. s1 = input('请输入:') # 'abc'
  16. s2 = input('请输入:') #'abc'
  17. print(s1 == s2) # True
  18. print(s1 is s2) # False 因为使用input函数指定的时候,生成的内存地址是不一样的
  19. # 打印长字符串 (\表示续行符,如果一行的代码太长,可以使用该符号换成多行写)
  20. s5 = 'Hello, welcome to python world, ' \
  21. 'My name is Terence.'
  22. print(s5)
  23. # 另外一种打印长字符串的方法(使用注释符号,好处是可以保留原文本格式)
  24. s6 = """
  25. The weather is good today~!
  26. I am very happy.
  27. what about you ?
  28. """
  29. print(s6)
  30. # 使用 + 号连接字符串
  31. print('Hello ' + 'Terence\n')

字符串的运算符

  • 使用 == 运算,运算结果是False,做!= 运算,结果是True;
  • 使用 %,作用是将字符串格式化
  • 使用 r, 表示保留原来的格式,有r 则不发生转义,没有r 则发生转义(例如:’)

    运算符之 +, +=, join( )【拼接】

  • 使用 +,作用是拼接两个字符串;

  • 字符串拼接:join ```python userName=’小明’ attribute=’身高是’ value=’182CM’ str1=’5月’ str2=’21日’ num=5

print(userName + attribute + value)

str1 += str2 print(str1)

num += 1 print(num)

  1. ```python
  2. # 使用指定的符号解开
  3. s = '-'.join('abc')
  4. print(s)
  5. # 使用指定的符号合并
  6. s1 = ['a','b','c']
  7. print(''.join(s1))

运算符之 * 【重复】

  • 当我们对一个字符串进行 运算的时候,这个字符串能够被重复;重复的次数取决于 后方的数值;

    1. a='小楼好帅!\n' #代码中的“\n”是换行符
    2. print(a*5)

    运算符之 in【在…里面】

  • 返回的是布尔类型结果; ```python name = ‘steven’

result1 = ‘t’ in name result2 = ‘t’ not in name print(result1) # 返回的是布尔类型 True False print(result2)

  1. <a name="4d43fb96"></a>
  2. ### 运算符之 [ ]【使用下标获取】
  3. - 通过[ ]只能获取一个字母;
  4. - 使用字符串下标记忆方法:正常是从0开始计数,今后使用的时候,就按正序号1开始计数,那么到第几位就需要x+1;
  5. ```python
  6. s1 = 'picture.png'
  7. print(s1[0]) # 截取第1位字符
  8. print(s1[1]) # 截取第2位字符
  9. print(s1[-1]) # 截取[倒数]第一个字符
  10. print(s1[-3]) # 截取[倒数]第3位字符

运算符之 [ : ]【切片或截取】

  • 视频连接
  • 切片就是从字符串里复制一段指定的内容,生成一个新的字符串, 注意: 在字符串中,空格也算一个字符; | s1= | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | . | A | B | C | | —- | —- | —- | —- | —- | —- | —- | —- | —- | —- | —- | —- | —- | —- | —- | | 索引号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | | 正序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | 反序号 | -14 | -13 | -12 | -11 | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
  1. s1 = '0123456789' # [:] 如果按索引值解释:包前不包后 如果按正负序号解释: 正序:从1开始; 负序:需要-1
  2. # 正方向索引 # 按索引值取值解释:包前不包后
  3. print(s1[:]) # 0123456789 # 截取 全部字符
  4. print(s1[:3]) # 012 # 截取 0~2之间的字符;
  5. print(s1[0:4]) # 0123 # 截取 0~3之间的字符; range(0,4) == [0:4]
  6. print(s1[1:6]) # 12345 # 截取 1~5之间的字符 (或者截取从2+1位开始,第5位结束)
  7. print(s1[:-3]) # 0123456 # 截取 0~倒数第3位之前的字符;
  8. print(s1[2:]) # 23456789 # 截取 2~末尾的字符
  9. print(s1[-5:]) # 56789 # 截取【倒数第5位】到【末尾】的字符
  10. print(s1[-5:-2]) # 567 # 截取【倒数第5位】到【倒数第2位之前】的字符

运算符之 [ :: ]【方向或步长】

语法:str [start : end : 方向/步长], 第二个冒号后面表示的是方向或是步长: 正数:正向, 负数:反向

  1. s2 = 'abcdefgh'
  2. print(s2[::-1]) # 倒序,截取全部字符
  3. print(s2[::-2]) # 倒序,从倒数第1位开始,每间隔1个字符截取字符
  4. print('----------------------------------')
  5. print(s2[1::2]) # 从第1+1位开始,以2个字符[步长]为间隔,正序截取到末尾的所有字符
  6. print(s2[2::2]) # 从第2+1位开始,以2个字符[步长]为间隔,正序截取到末尾的所有字符
  7. print(s2[2::3]) # 从第2+1位开始,以3个字符[步长]为间隔,正序截取到末尾的所有字符
  8. print('----------------------------------')
  9. print(s2[5::-1]) # 【倒序】截取【第6位】到【开始】的字符
  10. print(s2[5:2:-1]) # 【倒序】截取【第6位】到第3位之后的字符
  11. print(s2[:-6:-1]) # 【倒序】截取【末尾】到【倒数第6位之后】的字符
  12. print('----------------------------------')
  13. print(s2[-1:-6:-1]) # 【倒序】截取末尾到倒数第6位之后的字符
  14. print(s2[-2:-8:-2]) # 【倒序】从倒数第2位开始间隔1位截取到倒数第8位之后的字符
  15. # print(s2[3:9:2])
  16. ## “3”表示切片的起始位置为第4个字符(字符串中字符的索引位置从0开始)
  17. ## “9”表示切片的终止位置(终止位置不会被截取)
  18. ## “2”表示从左向右每隔1位进行截取(负数表示从右至左截取)

常用操作 - 大小写转换

方法:capitalize( ),title( ),upper( ),lower( )

  • x.upper( ): 字符串全部字符转换为大写;
  • x.lower( ): 字符串全部字符转换为小;
  • x.swapcase( ): 字符串全部字符大小写互换x.capitalize( ): 字符串首个单词首字母大写;
  • x.title( ): 字符串中全部单词首字母大写; ```python

    下面这些方法均不用写入参数,直接调用即可

    s = ‘i need Pycharm.’

print(s.capitalize()) #字符串首个单词首字母大写 print(s.title()) #字符串中全部单词首字母大写 print(s.upper()) #全部字符转换为大写 print(s.lower()) #全部字符转换为小写 print(s.swapcase()) #全部字符大小写互换

  1. ```python
  2. # 验证码案例
  3. import random
  4. # 生成由4个随机字母组成的一个验证码 ==> 做法:循环4次, 每循环一次, 产生一个随机数, 循环结束后, 将4个随机数拼接在一起
  5. s = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789'
  6. code = ''
  7. for i in range(4):
  8. ran = random.randint(0,len(s)-1) # 因为s = 'abc' print(s[3])这样的取值会报超出范围的错误,所以需要在整个字符串长度的基础上 -1, 避免这种情况的发生.
  9. code += s[ran] # code = code + 'V'
  10. print('验证码:'+code)
  11. # 提示用户输入验证码:
  12. user_input = input('请输入验证码:')
  13. if user_input.lower() == code.lower(): # 在验证验证码的时候, 将用户输入的验证码和系统产生的验证码都同时转为小写, 保证输入字符串的大小写一致.
  14. print('验证码输入正确')
  15. else:
  16. print('验证码输入错误')

常用操作 - 查找与替换

方法:find( ),index( ),rfind( ),rindex( )

  • 都可以获取指定字符串的下标;
  • find和rfind函数,于index和rindex函数的用法相同,只是在没有查询到结果时,返回值会为-1; ```python

    find:从左至右查询:

    find(str,start,end) # 检测str字符串是否包含在字符串中,可以指定范围,默认从头到尾,得到的是该字符串第一次出现的下标,如果没有查到没有,则返回-1;

index:从左至右查询:

index(str,start,end) 参数str:指被查询的字符或字符串; 参数start:查询的起始位置; 参数end:查询的终止位置(终止位置不在查询范围内);

rindex/rfind:从右至左查询:

rindex(str,start,end) #参数start和参数end:可同时省略,省略后查询字符串中全部字符,也可以只省略参数end,表示查询范围为起始位置至末尾; rfind(str,start,end)

  1. ```python
  2. s='人人为我,我为人人。'
  3. print(s.find('我')) # 返回从左至右,'我'第一次出现的位置
  4. print(s.find('我',2,len(s))) # 从索引位置2到结尾范围内查找
  5. print(s.find('他')) # 使用find的查找,如果该字符在字符串中没有找到, 则返回-1
  6. print('---------------------------')
  7. k='kaige is a very very nice man'
  8. print(k.rfind('nice'))
  9. print(k.rfind('is'))
  10. print(k.rfind('very',0,len(k)))
  1. # 查询指定字符的索引号
  2. s = '人人为我,我为人人.'
  3. print(s.index('人')) # 从左向右查询全部字符,如果被查询在字符不在字符串中, 会报错~~
  4. print(s.index('人',2)) # 从左侧第3个字符开始向右查询至末尾
  5. print(s.rindex('人')) # 从右向左查询全部字符
  6. print(s.rindex('人',0,8)) # 从右侧第9个字符之前向左查询至首位

替换
方法:replace

格式 说明
x.replace(old,new,count) old:表示需要被替换的字符串;
new:表示替换后的新字符串;
count:表示替换的次数,此参数可省略,省略则表示替换所有需要被替换的字符串;
  1. s='小楼好帅,我好喜欢他!'
  2. print(s.replace('喜欢','崇拜'))
  3. print(s.replace('好','很',1))
  4. print(s.replace('好','很',2))

常用操作 - 获取长度

方法: len( x )

  1. a = len('小楼是一个很帅的帅哥!')
  2. print(a) # 显示:11
  3. b = len('小楼是一个很帅的帅哥!'.encode('UTF-8'))
  4. print(b) # 显示:33,当我们对中文进行编码,采用“UTF-8”编码类型时,一个汉字的字节数量是3
  5. c = len('小楼是一个很帅的帅哥!'.encode('GBK'))
  6. print(c) # 显示:22,当我们对中文进行编码,采用“GBK”编码类型时,一个汉字的字节数量是2

常用操作 - 统计次数

方法: count(str[,start] [,end])

格式 说明
count(x,start,end) 这个函数可以统计字符串中被查询的字符或字符串出现的次数。

参数x : 指被查询的字符或字符串,参数start是查询的起始位置;

参数end : 查询的终止位置(终止位置不在查询范围内);

参数start和end可同时省略,这时为查询字符串中全部字符;也可只省略end,表示查询范围为起始位置至末尾
  1. str = 'kaige is a very very nice man'
  2. s = str.count( 'very',5, len(str))
  3. print(s)
  1. s='人人为我,我为人人。'
  2. print(s.count('人')) #计算字符串中被查询字符或字符串出现的次数
  3. print(s.count('人人')) #计算字符串中被查询字符或字符串出现的次数
  4. print(s.count('人',0,8)) #计算从字符串首位到第9个字符(不含第9个字符)之间被查询字符或字符串出现的次数

常用操作 - 使用分割符 [重]

方法: split( ),rsplit( ),splitlines( ),partition( ),rpartition( )

  1. #字符串类型的数据
  2. str01 = 'zhangsan-lisi-wangwu-jerry-henry-merry-jack-tony'
  3. #split方法: 可以将一个字符串切割成一个列表
  4. print(str01.split('-')) #使用分隔符‘-’来切割, 例如: str01.split('-',2) # 2表示使用'-'分割几次
  5. print(str01.split('-',2)) #使用分隔符‘-’来切割,从左至右切2次后,剩下的原封不动的成为一个列表元素
  6. print(str01.rsplit('-')) #结果与split一致
  7. print(str01.rsplit('-',2)) #使用分隔符‘-’来切割,从右至左切2次后,剩下的原封不动的成为一个列表元素
  8. #splitlines:按照行分隔,返回一个包含各行作为元素的列表
  9. str02 = 'hello \nworld'
  10. print(str02.splitlines())
  11. #partition: 指定一个字符串作为“分隔符”,分割成三部分,分隔符前,分隔符,分隔符后,这三部分组成一个元祖
  12. str03 = '今天天气好晴朗,处处好风光呀好风光'
  13. print(str03.partition('好'))
  14. print(str03.rpartition('好'))
  15. str04 = '2020.2.14拍摄不要打开.mp4'
  16. print(str04.rpartition('.'))

常用操作 - 处理空格或空白

方法: strip( ) lstrip( ) rstrip( )

strip( ) 去除字符串两端的空白
lstrip( ) 去除字符串开头的空白
rstrip( ) 去除字符串末尾的空白
strip(chars) 去除字符串两侧的指定内容,并且可以同时去除多个相同的指定内容;
chars: 为指定的一个或多个字符,不填入该参数则去除字符串两侧所有空格。
strip(chars) 去除字符串左侧的指定内容,并且,可以同时去除多个相同的指定内容;
chars: 为指定的一个或多个字符,不填入该参数则去除字符串左侧所有空格。
rstrip(chars) 去除字符串右侧的指定内容,并且,可以同时去除多个相同的指定内容;
chars: 为指定的一个或多个字符,不填入该参数则去除字符串右侧所有空格。
  1. str1 = ' 人人为我我为人人 '
  2. str2 = '人人为我我为人人'
  3. str3 = str1.rstrip() #注意,如果要永久删除空白,必须赋值给一个变量,再使用这个变量即可
  4. print(str1)
  5. print(str1.strip())
  6. print(str1.lstrip())
  7. print(str1.rstrip())
  8. print(str2.strip('人'))
  9. print(str2.lstrip('人'))
  10. print(str2.rstrip('人'))
  11. print(str2.strip('人人为'))

常用操作 - 字符串的判断函数

方法: starswith( ), endswith( ), isalpha( ), isdigit( ), isalnum( ), isspace( )

  • is开头的是用于判断的,结果是一个布尔类型; ```python print(‘hello’.startswith(‘he’)) # True 用于判断是否以xxx开头的 print(‘hello’.endswith(‘o’)) # True 用于判断是否以xxx结尾的 print(‘——————————-‘)

print(‘he4511o’.isalpha()) # False 用于检索和判断整个字符串中,是否全是字母,而当前字符串中夹杂有数字,所以返回False print(‘hello’.isdigit()) # False 用于检索和判断整个字符串中,是否全是数字 print(‘123’.isdigit()) # True print(‘1.23’.isdigit()) # False print(‘——————————-‘)

print(‘ab12hello’.isalnum()) # True 用于检索和判断整个字符串中,是否由字母【或】数字组成,如果有其他符号出现,就返回False print(‘abc.123’.isalnum()) # False print(‘——————————-‘)

print(‘ ‘.isspace()) # True 用于检索和判断整个字符串中, 是否全部由空格组成 print(‘hell o’.isspace()) # False

  1. <a name="50a325ff"></a>
  2. ### 常用操作 - 对齐补齐
  3. **方法: center( ) ljust( ) rjust( ) zfill( )**
  4. | **center(width[, fillchar])** | 返回一个指定宽度的居中字符串,fillchar为填充的字符串,默认使用空格填充 |
  5. | --- | --- |
  6. | **ljust(width[, fillchar])** | 返回一个指定宽度的左对齐字符串,fillchar为填充字符串,默认使用空格填充 |
  7. | **rjust(width[, fillchar])** | <br /> |
  8. | **zfill(width)** | 返回一个长度为width的字符串,原字符串右对齐,前面用0补齐 |
  9. ```python
  10. str = 'hello python'
  11. a = str.center(20,'*')
  12. print(a)
  13. b = str.ljust(20,'*')
  14. print(b)
  15. c = str.rjust(20,'*')
  16. print(c)
  17. d = str.zfill(20)
  18. print(d)

eval( )

eval (str) 和 int (str) 差不多,就是将字符串当成有效的表达式来求值,并返回计算结果(仅对有效的数值运算)

  1. sum = eval('12+3')
  2. print(sum)

字符串转其他类型数据

  1. str1 = '123'
  2. str2 = '1,2,3'
  3. str3 = 'a bb' # 这里有一个空格
  4. str4 = eval("{'name':'xellga', 'age':18}") # eval可以执行字符串中的代码
  5. print('***切分字符串成了列表***')
  6. print(str3.split(' '))
  7. print('\n***字符串转成列表***')
  8. print(list(str1))
  9. print(list(str2))
  10. print(list(str3))
  11. print(list(eval(str2)))
  12. print('\n***字符串转成元组***')
  13. print(tuple(str1))
  14. print(tuple(str2))
  15. print(tuple(str3))
  16. print('\n***字符串转成集合***')
  17. print(set(str1))
  18. print(set(str2))
  19. print(set(str3))
  20. print('\n***字符串转成字典***')
  21. print(str4)

练习题

练习题1

输入两个字符串,从第一个字符串中删除第二个字符串中所有的字符:
例如:输入’abcdefghijk’ 和 ‘cdfk’, 删除之后的字符串变成:’abeghij’

  1. s1 = input('请输入第一个字符串:')
  2. s2 = input('请输入第二个字符串:')
  3. s3 = ''
  4. for i in s1:
  5. if i not in s2:
  6. s3 += i # 这里就是字符串的添加方式,还有去重的效果
  7. print('s3的结果为:',s3)
  8. # 将s3的值替换掉原来的s1
  9. # 方法1
  10. s1 = s3 #直接将s3赋值给s1
  11. print('方法1替换s1后的结果为:',s1)
  12. # 方法2
  13. for j in s2:
  14. s1 = s1.replace(i,'') #每次从s2中获取到一个字符,如果这个字符出现在s1中,就替换成‘空字符’
  15. print('方法2替换s1后的结果为:',s1)

练习题2

1,循环提示用户输入:用户名,密码,邮箱(要求用户输入的长度不超过20个字符,如果超过则只有前20个字符有效)
2,打印输出
3,用户名 密码 邮箱
4,Admin 123 hfjs@163.com
5,Lily 111 yweuyr@163.com
6,如果用户输入q或是Q,则不再继续输入

  1. message = ''
  2. while True:
  3. username = input('请输入用户名:')
  4. password = input('请输入密码:')
  5. email = input('请输入邮箱:')
  6. username == username[0:20] #包前不包后,所以0:20表示不会超过20个字符
  7. password == password[0:20]
  8. email == email[0:20]
  9. meg_format = '{}\t{}\t{}'.format(username,password,email)
  10. meg = meg_format.expandtabs(4)
  11. message += meg
  12. if username == 'q' or username == 'Q' or password == 'q' or password == 'Q' or email == 'q' or email == 'Q':
  13. break
  14. print(message)

字符集


ASCII编码

计算机只能处理数字(其实就是数字0和1),如果要处理文本,就必须先把文本转换成数字才能处理,最早的计算机在设计的时候,采用的是8个比特(bit)作为一个字节(byte);
所以,一个直接能表示最大的整数就是255(十进制255 = 二进制11111111),0-255被用来表示大小写英文字母,数字和一些符号,于是这个编码被称为:ASCII编码;
ASCII码表使用7位二进制表示一个字符,它的区间范围是0-127,一共只能表示128个字符,仅能支持英语;

Latin1码表的形成

随着计算机科学的发展,西欧语言,希腊语,泰语,阿拉伯语等语言的字符也被添加到码表中,形成了一个新的码表:ISO8859-1(又被称为:Latin1码表);
ISO8859-1使用了8位二进制表示一个完整的字符串,并且前0-127位完全兼容ASCII码表;

Unicode的形成

Unicode(统一码,王国码,单一码)是计算机科学领域里的一项业界标准,包括字符集,编码方案等;
Unicode是为了解决传统的字符编码方案的局限性而产生的,它为每种语言中的每个字符都设定了统一并且唯一的二进制编码,以满足跨语言,跨平台进行文本转换和处理的要求;

BGK,utf-8,BIG5

既然有了Unicode编码,为什么还会出现BGK,utf-8,BIG5编码?比如:

  1. print(ord('你')) # 编码为:20320
  2. print(bin(20320)) # 二进制数为:0b100111101100000

根据编码规则

  • 使用Unicode为每种语言的每个字符都设定了唯一的二进制编码,但是它还是存在一定的问题,不够完美;
  • 例如:汉子“你”转换成一个字符结果为”0x4f60”,转换成二进制就是“01001111 01100000”,此时就有两个问题:
    • 1001111 01100000到底是一个汉字“你”,还是一个Latin1的字符?
    • 如果Unicode进行了规定,每个字符都使用n个八位来表示,但是对于Latin1字符来说,又会浪费很多存储空间;
  • 为了解决这个问题,就出现了一些编码规则,按照一定的编码规则对Unicode数字进行了计算,得出新的编码,在中国常用的字符编码有:GBK,BIG5和utf-8这三种编码规则;
    • GBK:国标库,简体中文,汉字占两个字节;
    • BIG5:繁体中文;
    • utf-8:统一编码,汉字占三个字节;

      字符和编码的相互转换

      ```python

      使用ord方法,可以获取一个字符对应的数字编码

      print(ord(‘a’))
      print(ord(‘你’))

使用chr方法,可以获取一个编码对应的字符

print(chr(65))

使用bin方法,可以获取一个数字的二进制,二进制数就是计算机可以识别的

print(bin(65))

  1. encode( ): 编码, 可以将字符串按照指定的编码格式转换成为二进制;
  2. ```python
  3. print('你'.encode('gbk')) # 结果为【两个字节】:b'\xc4\xe3' => 0xc4e3
  4. print(0xc4e3) # 换成成数值为:50403
  5. print(bin(0xc4e3)) # 转换成二进制为:11000100 11100011
  6. print('\n')
  7. print('你'.encode('utf8')) # 结果为【三个字节】:b'\xe4\xbd\xa0' => 0xe4bda0
  8. print(0xe4bda0) # 换成成数值为:14990752
  9. print(bin(0xe4bda0)) # 转换成二进制为:11100100 10111101 10100000

decode( ): 解码, 可以将一个二进制数据按照指定的编码格式转换成字符串;

  1. x = '你'.encode('utf8') # 通过encode方法将【字符串】按照utf8格式【转成二进制数】
  2. print(x)
  3. y = x.decode('utf8') # 通过decode方法将【二进制】按照utf8格式【解码成字符串】
  4. print(y)

出现乱码的情况

  1. # 把"你好"使用utf-8编码
  2. a = '你好'.encode('utf8') # utf8是一个汉字转成成三个字节
  3. print(a) # 结果:b'\xe4\xbd\xa0 \xe5\xa5\xbd'
  4. # 将变量a的结果通过gbk解码
  5. b = a.decode('gbk') # gbk是一个汉字占两个字节
  6. print(b) # 得到的结果为:浣犲ソ => \xe4\xbd \xa0\xe5 \xa5\xbd'
  7. # 将变量b中的一个字节通过gbk解码
  8. c = b'\xe4\xbd'
  9. print(c.decode('gbk')) # 得到的结果为:浣
  10. print(a.decode('utf8')) # 得到的结果为:你好

列表和元组


列表的定义及特点 :

  • 列表是有序的元素集合, 可以存放任何数据类型的数据,如: 所有字母的列表,所有数字的列表, 所有家庭成员的列表…..等等;
  • 列表使用方括号[ ]来表示,元素之间使用逗号分隔;
  • 列表元素是可变的, 可以修改;
  • 列表由于是有序的,所以每个元素都对应着一个索引来标识其位置,从0开始,要访问列表元素,只需将该元素的【名称】,【索引】或【位置】或告诉程序即可;
  • 列表中,第一个元素的索引号为0,第二个元素为1,要访问列表中的任何元素,都可将其位置减去1,得到的结果即为索引号,例如:要访问第四个列表元素,可使用索引3;
  • 列表中最后一个元素索引号为-1,索引-2为倒数第二个列表元素,索引-3返回倒数第三个列表元素,以此类推;

元组的定义及特点 :

  • 元组和列表特点相似;
  • 元组使用方括号( ) 来表示,元素之间使用逗号分隔;
  • 唯一区别:元组的元素不可变, 不能修改,只能查询;

    列表的创建

    1, 使用 range( )函数生成一系列数字:
    1. for value in range(1,5):
    2. print(value) # 只打印了数字1-4,因为函数range( )让Python从指定的第一个值开始数,并在到达指定的第二个值后停止,因此输出不包含第二个值(这里为5)
    3. # 要打印数字1~5,则需要使用range(1,6),所以使用range( )时,如果输出不符合预期,请尝试将指定的值+1或 -1;

2, 使用 range( ) 创建数字列表:

  1. # 创建数字列表,可使用函数list( )将range( )的结果直接转换为列表,将range( )作为list( )的参数,则输出将是一个数字列表:
  2. a = list(range(1,6))
  3. print(a)
  4. # 可指定步长
  5. b = list(range(1,6,2)) # 从1开始数,然后不断的+2,直到达到或超过6,因此输出1-6之间的所有基数
  6. print(b)

3, 使用range( )可以创建任何需要的数值集,例如:创建一个包含前10个整数 (即: 1-10) 的平方值列表 :

  1. print('***正常版本***')
  2. a = []
  3. for value in range(1,11): # 接下来,使用函数 range() 让Python遍历1~10的值
  4. b = value**2 # 在循环中,计算当前值的平方,并将结果存储到变量 b 中
  5. a.append(b) # 最后,将新计算得到的平方值附加到列表 a 的末尾
  6. print(a)
  7. print('\n***进阶版本***')
  8. a1 = []
  9. for value in range(1,11):
  10. a1.append(value**2) # 不使用临时变量 b, 直接将每个计算得到的值附加到列表的末尾
  11. print(a1)
  12. print('\n***高阶版本***')
  13. a2 = [value**2 for value in range(1,11)]
  14. print(a2)

高阶版本说明:

  • 使用这种语法,首先指定一个列表名 a2, 然后指定一个左方括号,定义一个表达式,用于生成要存储到列表中的值,在这个示例中,表达式为 value2**,用于计算平方值;
  • 接下来,编写一个 for 循环,用于给表达式提供值,再加上右方括号,在这个示例中,for 循环为 for value in range(1,11) ,它将值1~10提供给表达式 value2**;
  • 请注意,这里的 for语句末尾没有冒号;

列表可增删改查

  • 如果不确定该使用del语句还是pop( )方法,下面是一个简单的判断标准:如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用del语句;
  • 如果你要在删除元素后还能继续使用它,就使用方法pop( ) ```python print(‘====== 添加元素 ======’) list1 = [1,2,3]

list1.insert(0,9) # [句首]添加元素[0表示索引号,9表示新元素] print(list1)

list1.append(50) # [句尾]添加元素 print(list1)

list1.extend([60,70]) # [句尾]添加多个元素,注意: 必须将多个元素放在一个列表中, 就是说这些元素需要使用[] print(list1)

list1[3:3] = 11,22 # 在指定索引位置的前方插入新元素,列表[索引位置:索引位置] = 新元素, 注意: 两个索引位置要保持一致 print(list1)


```python
print('====== 修改元素 ======')
list2 = [1,2,3] 

list2[0] = 11                          # 修改指定位置的元素为新元素
print(list2)

list2[1:3] = 9,88                      # 修改指定范围内的元素为新元素,这里可以理解为:用新元素替换成指定范围内的元素
print(list2)                           # 注意:冒号前表示索引号(从0开始),冒号后表示元素所在的位置号(从1开始)
print('====== 取出[删除]元素 ======')
list3 = [1,2,3]  

list3_pop = list3.pop( )    # 该方法可以删除列表最后一个元素,返回值是删除的那个末尾元素,默认是删除最后一个,但是也可以指定下标来删除,如:list3_pop=list3.pop(2);
print(list3)                         
print(list3_pop)  

print('====== 删除元素 ======')
list4=[1,2,3]

list4.remove(2)             # 当不知道要从列表中删除的值所处的位置的时候使用,若列表中不存在与参数相同的元素则提示异常, 删除从左至右第一个与指定内容匹配的元素
print(list4)

print('====== 删除元素 ======')
list5=[1,2,3]
del list5[-1]               # 使用 del语句删除单个元素【条件是知道其索引】,使用 del语句将值从列表中删除后,就无法再访问它了
print(list5)

list6=[1,2,3,4,5]
del list6[1:3]             # 使用 del语句删除多个元素
print(list6)

print('====== 清空元素 ======')
list7=[1,2,3]

list7.clear()              # 清空列表,里面的所有元素全部删除
print(list7)

del list7[:]               # 清空全部元素
print(list7)
# 删除以下元素中带go的单词,防止漏删,使用下面的方法
words = ['hello','goods','gooo','world','digot','alphago']

w = input('请输入一个单词,删除包含有该单词的元素:')

i = 0 # 用于表示列表中的下标

leng = len(words)  # 6

while i<leng:
    if w in words[i]:
        del words[i]     
        leng -= 1         # 由于匹配一个删一个,那么原列表的元素也就少一个,而i+=1就导致列表索引超出范围.所以这里删一个就减少一个列表长度
        continue
    i += 1

print(words)
print('====== 查询列表 ======')
list1 = [10, 20, 30, 40, 50]
list2 = ['列表', '元组', '字典']
list3 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

# 通过下标获取元素
print(list1[0], list2[2])                  # 获取【指定位置】的元素,注意:索引位置从左至右是从0开始
print(list2[-1].title())                   # 获取【最后一个】的元素,注意:通过将索引指定为 -1,要求首字母大写
print(list3[2:8:2])                        # 获取【指定范围】的元素,注意:可通过设置间隔获取,俗称切片
print('My name is '+list2[-1].title())     # 使用列表中的值

# 通过元素获取下标和元素判断
print(list2.index('字典'))                  # 获取某个元素的【索引位置】
print(list3.count('d'))                    # 获取列表中某个元素【出现的次数】
print('y' in list3)                        # 判断列表中是否包含某个元素,如果包含,返回值为True,否则为False

# 操作列表和元素
print(list1+list2)                         # 【合并多个列表】为一个新列表
print(list1*2)                             # 【复制列表元素】为一个新列表
print(len(list1))                          # 获取【元素的数量】,注意:Python计算列表元素数时是从1开始,因此确定列表长度时,不会遇到差一的错误
print(max(list1))                          # 当列表中元素均为数值型时,获取列表中【数值最大的元素】
print(min(list1))                          # 当列表中元素均为数值型时,获取列表中【数值最小的元素】
# 列表切片
list3 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

print(list3[0:3])       # 0表示索引0,3表示取到索引3前面的那个值,结果显示3个;
print(list3[1:4])       # 从索引1开始,取到索引4前面的那个数,也就是从第2个数~第4个数的数值,结果显示3个;
print(list3[:4])        # 没有指定第一个索引,将从列表开头开始,要让切片终止于列表末尾,可使用类似语法,结果显示4个;
print(list3[2:])        # 提取从第3个元素到列表末尾的所有元素,可将起始索引指定为2,并省略终止索引;
print(list3[-3:])       # 负数索引返回离列表末尾相应距离的元素,-3将返回末尾3个元素;

# 遍历切片
for a in list3[:3]:     # 这里的代码没有遍历整个队员列表,而只遍历前三名队员;
    print(a.title())

列表的复制

1, 使用copy()方法复制列表

a = ['aa','bb','cc','dd']

b = a.copy()

print(id(a),a)
print(id(b),b)
import copy
a = ['hello','good',[100,200,300],'yes','ok']

# a1是a的浅拷贝,在嵌套列表中,浅拷贝只拷贝一层,当a列表中修改了内层列表的值,a1也会随之改变
a1 = a.copy()
print(a1)

a[2][0] = 111            # 修改a列表的值,然后查看a1列表的变化
print(a1)

# a2是a的深拷贝,将a列表原封不动的全部拷贝下来
a2 = copy.deepcopy(a)
print(a2)

2, 使用切片[:]复制列表, 这样会让Python创建一个始于第一个元素,终止于最后一个元素的切片列表;

a = ['aa','bb','cc','dd']  
b = a[:]                    # 然后创建了一个名为 b 的新列表, 在不指定任何索引的情况下从列表 a中提取一个切片,从而创建了 a列表的副本,再将该副本存储到变量 b 中;

print(id(a),a)
print(id(b),b)             # 打印每个列表,发现它们包含的元素相同;

3, 复制列表之后,查看确实存在了两个列表 a 和 b , 这时就可以分别进行操作;

a = ['aa','bb','cc','dd']
b = a[:]                            # 与上一个示例一样,首先将 a 的元素复制到新列表 b 中

a.append('ee')                      # 然后在列表 a 中添加 'ee'
b.append('yy')                      # 在 b 中添加 'yy'

print(a)
print(b)
  1. 如果将 a 直接赋值给 b,是【不能】得到两个列表的,例如:下例演示了在不使用切片的情况下复制列表的情况; ```python a = [‘aa’,’bb’,’cc’,’dd’] b = a # 切记,这里是将 a赋给了b,而不是将 a 的副本存储到 b中;这种语法实际上是让Python将新变量 b关联到 a中的列表,因此这两个变量都指向同一个列表;

当我们将 ‘ee’ 添加到 a 中后,它也会出现在 b中;同样,’yy’ 好像只被加入到了 b中,但它也会同时出现在两个列表中, 所以输出表明,两个列表是相同的,这并非是我们想要的结果:

a.append(‘ee’)
b.append(‘yy’)

print(a) print(b)


<a name="08926a61"></a>
### 列表的排序

- ** 方法 sort( ) : **
   - 正序排列 {永久性的};
   - 如果要按与字母相反的顺序排列,只需要向sort( )方法中传递参数 reverse=True 即可;
- **方法 reverse( ) : **
   - 反序排列{永久性的, 但可恢复};
   - 恢复到原来的排列顺序,只需对列表再次调用 reverse( ) 即可;
- ** 函数 sorted( ) :  **
   - 对列表进行临时排序;
   - 可以按指定的顺序显示列表元素,不会影响原始的排列顺序;
   - 如果要按与字母顺序相反的顺序显示列表, 只需要向函数sorted( ) 传递参数reverse=True 即可;
```python
nums = ['6','5','3','1','8','7','2','4']

# 使用列表的sort()方法,可以直接对列表正序排列,但无法恢复到原来的排列顺序
nums.sort()  
print(nums) 

# 按相反的顺序排列列表元素, 通过设置参数 reverse=True,转换为降序排列
nums.sort(reverse=True)                             d
print(nums)
nums1 = ['A','D','B','C']

# 倒着打印列表,和list[::-1]的结果一样
nums1.reverse()                     
print(nums1)

print(nums1[::-1])   # 结果也是倒着打印
nums2=['A','D','B','C']

# 这里使用的是内置函数sorted(),默认对列表进行升序的临时排序,不会改变原列表数据;所以需要用一个变量来接收它执行后的结果
x = sorted(nums2)                 
print(x) 

# 使用函数 sorted(),再传递参数 reverse=True对列表进行降序的临时排序,会改变原列表;
y = sorted(nums2,reverse=True)        
print(y)                         

# 查看原始排列顺序
print(nums2)

列表的遍历【for】

  • 你经常需要遍历列表的所有元素,需要对列表中的每个元素都执行相同的操作时,可使用Python中的for循环;
  • 对每个元素,都将执行循环指定的步骤,不管列表包含多少个元素,如果列表包含一百万个元素,Python就重复执行指定的步骤一百万次,且通常速度非常快;
  • 另外,编写for循环时,对于用于存储列表中每个值的临时变量,可指定任何名称; ```python magicians = [‘alice’,’david’,’carolina’]

for i in magicians:
print(i)

代码解析:

- for语句中, 首先获取列表 magicians 中的第一个值( 'alice' ),并将其存储到变量 i 中; 紧接着,执行print打印,它让Python打印 i 的值—> 依然是 'alice' ;
- 鉴于该列表还其他值,Python会返回到循环for语句中,获取列表中的下一个名字—> 'david' ,并存储到 i 中,然后继续执行print打印,再次打印 i 的值—>当前为 'david';
- 接下来,Python再次执行整个循环,对列表中的最后一个值——- 'carolina' 进行处理,至此,列表中没有其他的值了,因此Python接着执行程序的下一行代码;
- 在这个示例中, for循环后面没有其他的代码,因此程序就此结束!
```python
magicians = ['alice','david','carolina']  

for i in magicians:
    print(i.title() + ', that was a great trick!')

代码解析:

  • 对于每位魔术师,都打印一条消息,指出他的表演太精彩了,相比于前一个示例,唯一的不同是对于每位魔术师,都打印了一条以其名字为抬头的消息;
  • 循环第一次迭代时,变量 i 的值为 ‘alice’ ,因此Python打印的第一条消息的抬头为 ‘Alice’ ;
  • 循环第二次迭代时,消息的抬头为 ‘David’ ;
  • 循环第三次迭代时,抬头为 ‘Carolina’;
  • 最终输出表明,对于列表中的每位魔术师,都打印了一条个性化消息:”that was a great trick!”

for 循环体中可以包含多行代码,每个缩进的代码行都是循环体的一部分,针对列表中的每个值都会执行一次,所以,可以对列表中的每个元素执行任意次数的操作;

magicians = ['alice','david','carolina']  

for i in magicians:
    print(i.title() + ', that was a great trick!')  
    print('I can\'t wait to see your next trick, ' + i.title() + '.\n')

代码解析:

  • 由于两条 print 语句都缩进了,因此它们都将针对列表中的每位魔术师执行一次;
  • 第二条print 语句中的换行符 “\n” (第1处)在每次迭代结束后都插入一个空行,从而整洁地将针对各位魔术师的消息编组:

for循环结束后再怎么做呢?

  • 通常,你需要提供总结性输出或接着执行程序必须完成的其他任务, 在for循环后面,没有缩进的代码都只会执行一次,不会重复执行;
  • 下面打印一条向全体魔术师致谢的消息,想要在打印给各位魔术师的消息后面打印一条给全体魔术师的致谢消息,需要将相应的代码放在for循环后面,且不缩进: ```python magicians = [‘alice’,’david’,’carolina’]

for i in magicians: print(i.title() + ‘, that was a great trick!’)
print(‘I can\’t wait to see your next trick, ‘ + i.title() + ‘.\n’)

print(‘Thank you, everyone. That was a great magic show!’)


<a name="ffbffb6c"></a>
### 列表的遍历【while】
```python
magicians = ['alice','david','carolina'] 

i = 0
while i < len(magicians):
    print(magicians[i])
    i += 1

列表的嵌套

可以称之为多维数组,就是列表中再嵌套列表,例如:

nums = [1,
        2222,
        [100,200,300],
        ['aaa','bbb','ccc'],
        5,6,7,8,9
       ]

print(nums[2][2])    # 索引1中的索引2 ==》  [100,200,300]中下标为2的元素:300

nums[2][2] = 'abc'   # 把 300 修改成'abc'
print(nums)

print(nums[2][2])
print(nums[3][1][2])  # 获取'bbb'中的字符 b
# 一个学校,有3个办公室,现在有10个老师等待工位的分配,请编写程序,随机完成分配
import random

terchers = ['A','B','C','D','E','F','G','H','I','J']
rooms = [[],[],[]]                      # 有三个办公室,每个办公室要放人,所以需要使用到列表的嵌套

for tercher in terchers:                # 在老师的名单中遍历
    room = random.choice(rooms)         # 使用choice方法在rooms中随机选择一间办公室
    room.append(tercher)                # 每遍历一次得到的老师名字,就放进一间随即选择的办公室内
print(rooms)  

# 带下标我们一般使用while,for循环也可以带下标
for i,room in enumerate(rooms):
    print('第%d个房间有: %d个人,分别是:' %(i,len(room)),end='')
    for teacher in room:
        print(teacher,end=' ')    # 这个打印完成后需要换行,所以最后面就跟了一个print()
    print()

列表练习题

习题 1:输入一个姓名, 如果在列表中, 提示存在,如果不在列表中, 就将这个姓名添加进来

# 方法一
names = ['zhangsan','lisi','chris','jerry','henry']
username = input('请输入一个姓名:')
if username in names:
    print('用户名已经存在')
else:
    names.append(username)
print(names)
# 方法二
names = ['zhangsan','lisi','chris','jerry','henry']

username = input('请输入一个姓名:')
for i in names:
    if i == username:
        print('用户名已经存在')
        break

else:                      # 注意点在这里, 因为不能把else放在for循环中,比如i便利到李四的时候, 且username输入的是zhangsan,那么就会执行else语句, 把lisi再一次加入到列表中; 
    names.append(username)
print(names)

习题 2:求列表里最大的数,和最大数的下标

nums = [5,3,6,8,9,1,2,4,7]

nums.sort()        # 升序
print('nums1 = ', nums)
print('使用方法一:获取到nums列表中最大的数是: %d\n' %nums[-1])

nums.sort(reverse=True)   # 降序
print('nums2 = ', nums)
print('使用方法二:获取到nums列表中最大的数是: %d\n' %nums[0])
  • 使用代码的方式获取 ```python nums = [5,3,6,8,9,1,2,4,7]

x = nums[0] # 假设第0个元素是最大数

for i in nums: if i > x: # 如果发现列表里存在比假设还要大的数字,就把假设的值设置为发现的数字 x = i print(‘使用方法三:发现nums列表中最大的数是:%d, 它的下标为:%d’ %(x,nums.index(x)))


<a name="2c4ce23f"></a>
#### 习题 3:删除列表中的空字符串
```python
# 思路1:使用for...in遍历列表,如果遍历到空元素,则从原列表中移除,最后打印列表
words = ['hello','hi','','','123','heihei','']   # 目标:['hello','hi','123','heihei']

for word in words:
    if word == '':
        words.remove(word)
print(words)                 # ['hello', 'hi', '123', 'heihei', ''],最后多了一个空格,不是我们想要的结果            

# 注意:在使用for...in循环遍历列表时,最好不要对列表进行增删操作
# 思路2:使用while遍历列表,如果遍历到空元素,则从原列表中移除,最后打印列表
words = ['hello','hi','','','123','heihei','']

i = 0
while i < len(words):
    if words[i] == '':
        words.remove(words[i])
        i -= 1
    i += 1
print(words)
# 思路3:遍历列表,把不为空的元素添加到新的列表中,最后覆盖原来的列表,并打印
words = ['hello','hi','','','123','heihei','']

list = []
for word in words:
    if word != '':
        list.append(word)
words = list
print(words)

元组的创建

tup1 = ()                               # 创建空的元组
tup2 = (1,)                             # 当元组只有一个元素时,要在元素后方添加逗号[重点]
tup3 = (1,2,3)                          # 当元组有多个元素时,元素之间以逗号分隔
tup4 = (1,1.0,'abc','abc'.upper())      # 元组中的元素可以为Python中所有的对象

print (tup1)
print (tup2)
print (tup3)
print (tup4)

元组仅查询

tup1 = (1,2,3,4,5,6,7,8,9)         
tup2 = ('a','b','c')
tup3 = ('你','我','你','他','我','我')

# 根据索引查元素
print(tup1[0])                      # 从左至右,获取元组中索引为0位置的单个元素 ==> 元组[索引]
print(tup1[-1])                     # 从右至左,获取元组中索引为-1位置的单个元素 ==> 元组[-索引]
print(tup1[2:8:2])                  # 获取元组中指定范围内的多个元素 ==> 元组[起始位置:终止位置:间隔数量]

# 操作元组和元素
print (tup1+tup2)                    # 连接多个元组为一个新元组
print (tup2*3)                       # 重复元组元素为一个新元组
print (len(tup1))                    # 获取元组的元素数量, 显示有多少个元素
print (max(tup1))                    # 获取同一类型元组中最大的元素
print (min(tup1))                    # 获取同一类型元组中最小的元素

# 通过元素获取下标和元素判断
print(tup3.count('我'))                # 获取元组中某个元素出现的次数 ==> 使用count(object)函数,参数object为对象
print('a' in tup1)                  # 判断元组中是否包含某个元素,如果包含,返回值为True,否则为False
print(tup1.index(3))                # 查询元组中某个元素的索引位置 ---> 使用index(object,start,stop)函数;
                                        # object为对象,start为查询起始位置,stop为终止位置
                                        # 在元组的元素中查询到与参数相同的元素时,返回该元素的位置,否则抛出异常 ---> 结果为【int类型】

元组的遍历

# 遍历元组
dimensions = (200,50)  

for i in dimensions:
    print(i)

#要修改元组,只能重新定义整个元组
dimensions = (400,100)   

for j in dimensions:
    print(j)

列表/元组转其他数据类型

list1 = [123]  
list2 = ['123']
list3 = ['1,2,3']
list4 = ['1','2','3']
list5 = [['key1','value1'],['key2','value2'],['key3','value3']]
list6 = [5,6,7]
list7 = [8,9,0] 
list8 = [('1',1),('2','jiqw'),('3',1372)] 

print('***列表转成字符串***')
print(str(list1))
print(''.join(list2))
print('---'.join(list4))
print(''.join(str(list1)).join(list4))

print('\n***列表转成元组***')
print(tuple(list1))
print(tuple(list2))
print(tuple(list4))

print('\n***列表转成集合【去重】***')
print(set(list1))
print(set(list2))
print(set(list4))

print('\n***列表转成字典***')
# 情况1:如果分别有两张列表或是元组 (则使用zip( )函数即可转换) 
# 情况2:必须符合字典key:varlue的形式存在的元素才能转换
print(dict(list5))
print(dict(list8))
print(dict(zip(list6,list7)))

集合(set)


元组的定义及特点 :

  • 集合是一个无序的,不可重复的元素集;
  • 集合使用大括号{}或者set(iterable)函数进行创建,参数iterable为可迭代对象:可通过(字符串、元组、列表)进行创建;
  • 集合元素不可变, 不能修改;

    集合的创建【set】

    创建集合注意:
  • 1, 创建一个空集合必须使用 x = set( ),也不是 x ={},因为 x ={}是用来创建一个空字典的;
  • 2, 不能将可变的数据结构作为集合元素, 例如: 列表;

小技巧:如何去重元素:

  • 将数据结构转成集合即可! ```python

    直接赋值

    s1 = {1,2,3,4,5} # 直接使用大括号定义,必须要写入元素,不写元素就是一个空字典了

    s2 = {1, [‘a’, ‘b’, ‘c’]} # 报错:TypeError: unhashable type: ‘list’,因为集合中的每个元素要符合不可变这个规则,列表可变,不符合规则,报错了。

    s3 = {1, (‘a’, ‘b’, ‘c’)} # 不报错:元组不可变,符合规则,所以解释器不会跟你叫劲。

通过set()创建

s4 = set()
s5 = set(‘abcdefg’) # 通过字符串创建:会将字符串分解为【单个集合的元素】 s6 = set([‘a’,’b’,’c’,’d’]) # 通过列表创建:会将列表元素分解为【单个集合的元素】—> 注意要和上面的s2区分出来,s2是将一个列表当成了集合的一个元素,所以报错! s7 = set((‘a’,’b’,’c’,’d’)) # 通过元组创建:会将元组元素分解为【单个集合的元素】

print(s1) print(s3) print(s4) print(s5) print(s6) print(s7)


<a name="a1052163"></a>
### 集合仅增删
**添加集合元素 :** 

- add(element) 方法: 
   - 用于添加单个元素:参数element为集合允许添加的元素(数字、字符串、元组);【不可添加:列表和字典, 因为集合单个元素不可变, 可哈希】;
- update(iterable) 方法:
   - 用于添加多个元素:会去重,参数iterable为可迭代的对象(字符串、元组、列表);【不可添加:数字和字典】;

**注意:因为集合元素是无序的,所以每次显示输出的结果在顺序上会不一致;**
```python
s1 = set('123')
s2 = set('456')
s3 = set('abc')

# 添加单个元素,add()添加的是一个个集合的元素
s1.add(111) 
s1.add('4')               
s1.add((4,5,6)) 

# 添加多个元素
s3.update('defwy')             # 添加字符串到集合,字符串会被分解为单个元素后添加到集合
s3.update(['11','22','aa'])    # 添加一个列表到集合,列表元素会被分解为单个元素后添加到集合
s3.update((1,2,3))             # 添加一个元组到集合,列表元素会被分解为单个元素后添加到集合

#显示输出
print(s1)                       
print(s2)                     
print(s3)

取出, 删除一个元素, 清空列表元素

  • pop( )方法:
    • 随机取出一个元素, 并删除;
  • remove(element)方法:
    • 删除指定的元素,参数element为需要删除的元素;当集合中不存在这两个方法参数中填入的元素时,remove( )方法会抛出异常;
  • discard(element)方法:
    • 删除指定的元素,参数element为需要删除的元素;当集合中不存在这两个方法参数中填入的元素时,discard( )方法则不会受到影响;
  • clear( )方法:
    • 集合支持clear( )方法进行清空, 返回空集合; ```python

      使用pop( )方法取出一个集合元素(一般删除第一个元素)

      s = set([‘a’,’b’,’c’,’d’,’e’])

x = s.pop() print(‘随机取出一个元素:’,x)
print(‘随机取出一个元素后的集合为:’,s)


```python
s1 = set(['a','b','c','d','e'])
s2 = set(['a','b','c','d','e'])

#删除元素
s1.remove('c')
s2.discard('c')  
# s2.remove('h')    # 抛出异常
s1.discard('h')   # 不会报错

print(s1)   
print(s2)
s = set(['a','b','c','d','e'])

s.clear()   #清空集合
print(s)

元素的拼接

  • union( ) 方法 :
    • 将多个集合合并,生成一个新的集合;
  • update( ) 方法 :
    • A.update(B), 将B拼接到A里; ```python s1 = {‘a’,’b’,’c’,11,22}

s1.update({‘ok’,’up’}) # 在原集合中进行拼接 print(s1)

s2 = s1.union([1,2,3],’hello’,{‘ss’,’yy’}) # 生成新的集合 print(s2)


<a name="794891af"></a>
### 集合的复制

- 使用copy( )方法能够对集合进行复制
```python
a=set('小楼一夜听春语')          # 创建集合存入变量a
b=a                            # 创建变量b引用变量a的集合

c=a.copy()                     # 创建变量c复制变量a的值
print(a)                       # 显示输出结果为:{'春','夜','楼','听','语','小','一'}
print(b)                       # 显示输出结果为:{'春','夜','楼','听','语','小','一'}
print(c)                       # 显示输出结果为:{'春','夜','楼','听','语','小','一'}

a.remove('一')                  # 删除变量a中集合的一个元素
print(a)                        # 变量a发生改变,显示输出结果为:{'春','夜','楼','听','语','小'}
print(b)                        # 变量b因为引用变量a,同样发生改变,显示输出结果为:{'春','夜','楼','听','语','小'}
print(c)                        # 变量c没有改变,显示输出结果为:{'春','夜','楼','听','语','小','一'}

代码中,b = a实际上是将b指向了a的内容,所以当a的内容发生变化时,b同步发生了变化,而c = a.copy( )则是将a的内容真正进行了复制,不再受a的变化影响;
image.png

成员关系


Python中提供了一些方法让我们能够判断一个集合中是否包含某一元素;也可以判断一个集合是否是另一个集合的子集或超集;还可以判断一个集合与另一个集合是否没有交集;
image.png

  • in:可以用来判断操作符前方的值是否被后方的序列包含(成员关系);
  • not in:可以用来判断操作符前方的值是否没有被后方的序列包含(非成员关系);
  • issubset (set):可以用来判断集合是否是指定集合的子集,参数set为集合;如果成立返回结果为True,否则为False;
  • issuperset (set):可以用来判断集合是否是指定集合的超集,参数set为集合;如果成立返回结果为True,否则为False;
  • isdisjoint (set):可以用来判断集合是否与指定集合不存在交集,参数set为集合;如果成立返回结果为True,否则为False; ```python s1=set(‘好好学习’) s2=set(‘天天想上’) s3=set(‘好好学习天天想上’)

print(‘好’in s1) #显示输出结果为:True print(‘好’not in s2) #显示输出结果为:True print(s1.isdisjoint(s2)) #显示输出结果为:True print(s1.issubset(s3)) #显示输出结果为:True print(s3.issuperset(s1)) #显示输出结果为:True


<a name="854be07d"></a>
### 交集/并集/补集/差集
![](https://gitee.com/tt_picture/image/raw/master/python/20210502225704.png#crop=0&crop=0&crop=1&crop=1&id=b0GQf&originHeight=770&originWidth=1053&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)
```python
x = {1, 2, 3, 4, 5, 6, 7, 8}
y = {0, 1, 2, 4, 5, 9}
print(x - y)            # 差集:获取x集合去除与y集合交集元素后的全部元素:{3, 6, 7, 8}
print(x & y)            # 交集:获取两个集合中相同的元素:{1, 2, 4, 5}
print(x ^ y)            # 与非集:获取两个集合各自独有的元素【去掉了两个重复的部分】:{0, 3, 6, 7, 8, 9}
print(x | y)            # 并集:获取两个集合的全部元素【会去重】:{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
# 创建集合
s1 = set('Python')
s2 = set('PyCharm')

# 【交集】:获取两个集合中相同的元素
print(s1&s2)                               
print(s1.intersection(s2))                 

# 【并集】:将两个集合并在一起,取所有的元素【注意:如果有重复的会自动去重,因为这是集合的特点:唯一的】
print(s1|s2)                                  # 显示输出结果为:{'y','a','C','o','P','n','t','m','r','h'}
print(s1.union(s2))                           # 显示输出结果为:{'y','a','C','o','P','n','t','m','r','h'}

# 【差集】:获取当前集合去除与另一集合交集元素后的全部元素。
print(s1-s2)                                  # 显示输出结果为:{'o','t','n'}
print(s1.difference(s2))                      # 显示输出结果为:{'o','t','n'}
print(s2-s1)                                  # 显示输出结果为:{'m','a','r','C'}
print(s2.difference(s1))                      # 显示输出结果为:{'m','a','r','C'}

# 【与非集】:获取两个集合各自独有的元素【去掉了重复的部分】。
print(s1^s2)                                   # 显示输出结果为:{'o','t','m','a','r','n','C'}
print(s1.symmetric_difference(s2))             # 显示输出结果为:{'o','t','m','a','r','n','C'}

输出时改变集合的内容

# 第一种:difference_update(set) 函数,能够将当前集合和指定集合进行补集运算,并将当前集合内容更新为运算结果:
s1 = set('1234')
s2 = set('456')

s1.difference(s2)                  # 该操作对s1内容无影响,输出结果为:{'3','4','2','1'}
print('一,',s1)                        
s1.difference_update(s2)           # 更新集合s1的内容为【s1-s2】后的结果,s1内容被更新,输出结果为:{'3','2','1'}
print('二,',s1)                        

# 第二种:intersection_update(set) 函数,能够将当前集合和指定集合进行交集运算,并将当前集合内容更新为运算结果:
s1 = set('1234')
s2 = set('456')

s1.intersection_update(s2)         # 更新集合s1的内容为【s1&s2】后的结果:输出结果为:{'4'}
print('三,',s1)                   

# 第三种:symmetric_difference_update(set) 函数,能够将当前集合和指定集合进行差集运算,并将当前集合内容更新为运算结果:
s1 = set('1234')
s2 = set('456')

s1.symmetric_difference_update(s2)  # 更新集合s1的内容为【s1^s2】后的结果,输出结果为:{'6','3','2','5','1'}
print('四,',s1)

字典(dict)


使用列表的缺点

当存储的数据要动态添加,删除的时候,我们一般使用列表,但是,列表有时候会遇到一些麻烦,比如:

  • 列表中每个元素到底代表的是什么?
    • 列表只能存储值,但是无法都值进行描述 ```python

      定义一个列表,保存姓名,性别,职业

      namelist = [‘zhangsan’,’男’,’木匠’]

当修改职业的时候,需要记忆元素的下标

namelist[2] = ‘铁匠’

如果列表的顺序发生了变化,比如:添加了年龄

namelist = [‘lisi’,18,’男’,’铁匠’]

此时需要记忆新的下标,才能完成职业的修改

namelist[3] = ‘教师’

那么有没有一种方法,既能存储多个数据,又能在访问元素的时候很方便的定位到需要的那个元素呢?
<a name="71bc461f"></a>
### 字典的定义及特点

- 字典是一个无序的, 可以存储任意类型对象的数据,好比它是一个表格,只有两个字段,一个字段为key,另一个字段为values,"key : values"的形式就称为字典元素 ;
- 字典的键与值之间用冒号(:)隔开,元素之间以"key : values"的形式存在,每个元素之间用逗号分开,最后整体放在一个大括号{}中;
- 字典的元素中,key是唯一的,不可变的 ; valus是可变【可以增删改查】;

![](https://gitee.com/tt_picture/image/raw/master/python/20210502225713.png#crop=0&crop=0&crop=1&crop=1&height=491&id=mt4Vf&originHeight=655&originWidth=1566&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=1175)
<a name="8cf36547"></a>
### 字典的创建
```python
# 在{}中创建
d = {}                                     # 创建空字典
d = {'A':['a','aa','aaa'],'B':20}        # 通过指定[键:值]的方式来创建字典 

# 使用dict()方法创建
d = dict( )                                                  
d = dict(name='zhangsan', age=18)        # 通过[可变参数]来创建字典                          
d = dict([('A',100),('B',200)])          # 通过[列表]来创建字典,注意:列表中的元素必须是成对出现,多一少一都不行                                
d = dict((('A',100),('B',200)))          # 通过(元组)来创建字典,注意:元组中的元素必须是成对出现,多一少一都不行                              

d = dict(zip(['A','B'],[100,200]))       # 通过dict()的zip()函数联合使用创建字典
print(d)

d1 = {'a':'test',('a','b'):'test'}       # 其中有一个key值是一个元组,元组不可变,没问题;
# d2 = {'a':'test',{'a','b'}:'test'}     # 会报错,key需要的是不可变的对象,第二种里有一个集合,集合可变的,不符合key的规则,所以解释器跟你急了;

将列表转成字典【good】

# 通过fromkeys(seq,value)方法将一个列表创建成字典,参数seq为key的序列元素,参数value为key的默认值
list = ['A','B']                           

di1 = dict.fromkeys(list)  
di2 = dict.fromkeys(list,100) 
di3 = dict.fromkeys(list[0],100)  
di4 = dict.fromkeys(list[1],100)                                        

print(di1)                                # 输出为:{'A': None, 'B': None}                
print(di2)                                # 输出为:{'A': 100, 'B': 100}
print(di3)                                # 输出为:{'A': 100}
print(di4)                                # 输出为:{'B': 100}

字典的增删改查

添加一个元素

  • 方法1:字典[键] = 值 的方式进行添加,如果字典中不存在相同的键, 则自动添加,否则修改已存在键所对应的值;
  • 方法2:setdefault(k,default) 的方式进行添加,参数k为指定的键,参数default为默认值;
    • 当存在指定的键时,则返回该键所对应的值;
    • 当不存在指定的键时,则返回参数default设置的值,同时,也会添加新元素,键为: 参数k,值为: 参数default; ```python

      方法1

      d1 = {‘A’:100,’B’:200}

d1[‘C’] = 300 # 添新元素到字典 d1[‘D’] = 400,444 # 添加一个元组到字典

d1[‘E’] = d1.get(‘E’,’’) + ‘500’ d1[“F”] = d1.get(‘F’,’600’) d1[“G”] = d1.get(‘G’,0) + 700

print(d1)

方法2

d2 = {‘A’:100,’B’:200}

print(d2.setdefault(‘A’,’111’)) # 字典中存在相应的键,则返回该键对应的值,输出结果为:100 print(d2.setdefault(‘C’,’300’)) # 字典中不存在相应的键,则返回default参数的值,输出结果为:300

print(d2) # 当字典中不存在相应的键时,添加新元素 {‘A’: 100, ‘B’: 200, ‘C’: ‘300’}


<a name="1705c5be"></a>
#### 添加多个元素

- **update(m,kwargs) **的方法进行添加:
```python
d = {'A':100,'B':200}

# 通过可变参数添加多个元素
d.update(C=300,D=400)             
print('情况1:',d)                          

# 通过元组添加多个元素
d.update((('C',300),('D',400)))       
print('情况2:',d)                     

# 通过列表添加多个元素
d.update([('C',300),('D',400)])       
print('情况3:',d)   

# 通过字典添加多个元素
d.update({'C':100,'D':400})           
print('情况4:',d) 

# fromkeys(iterable,value) 批量设置,所有的值都是一样的, 不会改变原有字典
d.fromkeys('E',500)
print('情况5:',d)

查询

方法1:通过key取value,dict[key] => 获取对应的values(通过字符串的key键查找)
方法2:通过values()方法 => 获取所有的values
方法3:通过get(k,default)方法 => 参数k为查询的键,参数default为未查询到结果时的默认值,如果默认值不指定,返回None

d = {'A':100,'B':200}

print(d['A'])
print(d['B'])     

print(d.values())  

print(d.get('A','111')) 
print(d.get('C','222')) 

# 获取所有的key
for k,v in d.items():         # d.items(): => 结果是一个元组  
    print(k,v)

get( )方法的另一种用法

du = {}

du["name"] = du.get("name", "") + "zyb"

print(di)                                   # {'name': 'zyb'}

修改, 取出及删除

  • 修改某个键对应的元素:字典 [键] = 新值 ```python d = {‘A’:100,’B’:200}

d[‘A’]=’111’

print(d)


- 使用**pop(k,default)**方法在字典中**取出**指定元素的值,参数**k:**为指定元素的键,参数**default:**为未取到结果时的默认值,往往可以设定为:没有找到对应的key时,提示的消息;
- 使用**popitem( )**方法在字典中**取出**元素,结果是被删除的这个元素组成的键值对(一般是从末尾开始删除元素)
```python
d = {'A':100,'B':200,'C':300}
x = d.pop('A')   
print(x)          # 结果为:100    
print(d)          # 结果为:{'B': 200, 'C': 300},把A对应的键值对删除了

print('-------------------------------------')
d1 = {'A':100,'B':200,'C':300}  
x1 = d1.pop('D','111')               # 当key键‘D’不存在时,最后显示为111    
print(x1)                            # 结果为:111
print(d1)                            # 结果为:{'A': 100, 'B': 200, 'C': 300}

print('-------------------------------------')
d2 = {'A':100,'B':200,'C':300}  
x2 = d2.popitem()                  
print(x2)                            # 结果为:('C', 300)  ==> 说明删除的是字典中的一个元素
print(d2)                            # 结果为:{'A': 100, 'B': 200}
  • 使用del指令可以通过键删除某个元素:del 字典[键] ```python d4 = {‘A’:100,’B’:200,’C’:300}

del d4[‘B’] print(d4) # 结果为:{‘A’: 100, ‘C’: 300}


- 使用clear( ) 清空字典
```python
d3 = {'A':100,'B':200,'C':300}

x3 = d3.clear()
print(x3)                            # 结果为: None
print(d3)                            # 结果为: {}

合并

# 列表可以使用加号【+】和【extend()方法】将两个列表合并成一个列表
a = [1,2,3,4,5]
b = [5,6,7,8,9]
print('\n列表使用+号进行合并:',a + b)

a.extend(b)
print('列表使用extend()方法合并:',a)

print('-------------------------------------')

# 元组只能使用加号【+】进行合并
word1 = ('a','b','c')
word2 = ('c','d')
print('元组只能使用+号进行合并',word1 + word2)

print('-------------------------------------')

# 字典只能使用【update()方法】进行合并
d1 = {'A':100,'B':200}
d2 = {'C':300,'D':400}

d1.update(d2)
print('字典只能使用update()方法进行合并',d1)

排序

d = {"in": 123, "to": 511, "she": 255, "i": 111}

print(sorted(d.items(),key=lambda item:item[1], reverse=True))   # [('to', 511), ('she', 255), ('in', 123), ('i', 111)]

"""
di.items() 将字典转化为可迭代对象,Dict.items()将字典中的key-value元素,转化为了元组;
# [('in', 123), ('to', 511), ('she', 255), ('i', 111)]

key=lambda item: item[1] 取元素中的第二个元素作为比较的参数
"""

遍历

第1种遍历方式:使用for…in循环

d1 = {'A':100,'B':200,'C':300,'D':400}

for x in d1:                            # x获取到的都是key值
    print(x,'=',d1[x])

print('-------------------------------------')

for v,y in d1.items():                     # 使用拆包,多变量遍历
    print(v,'=',y)

第2种遍历方式:通过items( )方法获取字典中【所有的元素】

d2 = {'A':100,'B':200,'C':300,'D':400}

for i in d2.items():                     # d2.items() ==> 实际上是将字典转换成了一个列表,列表中每个元素是一个元组,每个元组由字典的键和值组成
    print(i[0],'=',i[1])

第3种遍历方式:使用keys( )方法获取到【所有的key】,然后再遍历key,根据key获取values

d3 = {'A':100,'B':200,'C':300,'D':400}

for k in d3.keys():
    print(k,'=',d3[k])

第4种遍历方式:使用values()方法直接获取到【所有的values】,并且只能获取到values ==> 所以用的不多

d4 = {'A':100,'B':200,'C':300,'D':400}

for v in d4.values():
    print(v)

字典实现一键多值

  • 一个字典就是一个键对应一个单值的映射;
  • 如果一个键映射多个值,那么就需要将这多个值放到另外的容器中, 比如列表或者集合里面;
  • 比如,你可以像下面这样构造这样的字典:

    d = {'a' : [1, 2, 3],'b' : [4, 5]}
    e = {'a' : {1, 2, 3},'b' : {4, 5}}
    
  • 选择使用列表还是集合取决于当前的实际需求,如果想保持元素的插入顺序就应该使用列表, 如果想去掉重复元素就使用集合(注意集合不会关心元素的顺序问题)

  • 可以很方便的使用 collections 模块中的 defaultdict 来构造这样的字典;
  • Python的字典{ }以键值对的形式保存数据,可以以键来访问字典中保存的值,字典不能用下标访问,字典中几乎可以包含任意的变量,字典,数列,元组。数列也一样。
  • python的列表[ ]与字典不同,列表通过单个元素来保存内容,通过下标访问元素。
  • python字典嵌套列表实现的就是{key1:[ ] , key2:[ ] ,…},其中,append() 方法用于在列表末尾添加新的对象;
  • Python字典 setdefault( ) 函数和get( )类似, 如果键不存在于字典中,将会添加键并将值设为默认值。
  • Python字典 in 操作符:用于判断键是否存在于字典中,如果键在字典dict里返回true,否则返回false。
    • defaultdict 的一个特征是:它会自动初始化每个 key 刚开始对应的值,所以只需要关注添加元素操作就可以了,比如: ```python print(‘方案一: list作为dict的值,值允许重复——-‘) d1 = {}

key = ‘A’ value = 2

d1.setdefault(key,[]).append(value)

value = 2 # 列表允许重复,所以添加相同的value d1.setdefault(key,[]).append(value) print(d1)

print(‘获取值:’) print(d1[key])

print(‘删除值,会留下一个空列表(删两次):’) d1[key].remove(value) d1[key].remove(value) print(d1)

print(‘检查是否还有一个值:’) print(d1.get(key,[]))


```python
dict = {}
dict['list'] = []
dict['list'].append([1,2,3,4])
dict['list'].append([5,6,7])
dict['list'].append([7,8,9,0,10])
dict
tdict={}

f=open('f1')


while True:
    line=f.readline().strip()
    if not line:
        break

    pos1=line.split()[0]
    pos2=line.split()[1]
    pos3=line.split()[2]

    if pos1 not in tdict:
        tdict[pos1] = {}
        tdict[pos1][pos2] = [pos3]

    else:
        if pos2 not in tdict[pos1]:
            tdict[pos1][pos2] = [pos3]

        else:
            tdict[pos1][pos2].append(pos3)
print('方案二: list作为dict的值,值允许重复-----')
d2 = {} 

key = 'A' 

keyin = 1 
value = 11 

d2.setdefault(key,{})[keyin] = value 

keyin = 2 
value = 22 
d2.setdefault(key,{})[keyin] = value 

keyin=3 
value=33 
d2.setdefault(key,{})[keyin] = value  
print(d2)

print('获取值:')
print(d2[key])

print('删除值,会留下一个空列表:')
del d2[key][keyin] 
keyin = 2 

del d2[key][keyin] 
print(d2) 

print('检查是否还有一个值:')
print(d2.get(key,()))
print('方案三 使用set作为dict的值 值不允许重复-----')
d3 = {} 
key = 'A'
value = 2 

d3.setdefault(key,set()).add(value) 
value = 2 
d3.setdefault(key,set()).add(value) 
value = 3 
d3.setdefault(key,set()).add(value) 

print(d3) 

print('获取值:')
print(d3[key]) 

print('删除值,会留下一个空列表:')
d3[key].remove(value) 
value = 2 
d3[key].remove(value) 
print(d3)  

print('检查是否还有一个值:')
print(d3.get(key,()))

字典转其他数据类型

dict = {'name': 'Zara', 'age': 7, 'class': 'First'}

print('***字典转成字符串***')
print(type(str(dict)),str(dict))

print('\n***字典转成列表(键)***')
print(list(dict))

print('\n***字典转成列表(值)***')
print(dict.values())

print('\n***字典转成元组(键)***')
print(tuple(dict))

print('\n***字典转成元组(值)***')
print(tuple(dict.values()))

字典的练习

# 列出每一个字符出现的次数    ==》结果可以使用字典来保存 {'a':4,'c':2,'x':2,'d':1,'p':1,'t':1,'s':1}
chars = ['a','c','x','d','p','a','x','t','a','c','s','a']

a = {}
for i in chars:
    if i not in a:
        a[i] = chars.count(i)    # 遍历到一个元素,如果空字典中不存在,则把它加进去,出现的次数 = 统计一下该元素在原列表中出现的次数,然后赋值
print('最终生成的a字典为:',a)

# 取其中最大数,使用max()
vs = max(a.values())   # 取所有的值中的最大的值
print('a字典中最大值为:',vs)

# 通过最大values值找到对应的key
for k,v in a.items():
    if v == vs:
        print('a字典中最大值对应的key为:',k)
chars = ['a','c','x','d','p','a','x','t','a','c','s','a']

a = {}
for i in chars:
    if i in a:     # 如果遍历的一个元素在字典里面
#         print('a字典里面已经有了这个字符%s' %(i))
        a[i] += 1   # 如果空字典中有了这个值,就把它的values +1
    else:
#         print('a字典里面没有这个字符%s' %(i))
        a[i] = 1     # 如果空字典中没有这个值,就把它放进来,然后赋值values = 1
print(a)
persons = [
    {'name':'zhangsan','age':18},
    {'name':'lisi','age':20},
    {'name':'wangwu','age':19},
    {'name':'jerry','age':21},
]

# 让用户输入姓名,如果姓名已经存在,提示用户,如果姓名不存在,继续输入年龄,并存入到列表中

数据结构之间的通用方法