数据类型:列表

官方是这样定义的,列表是一种有序的集合,可以随时增加或删除其中的元素,标识是中括号[]。比如

  1. list=['小明',18,1.70]

你有没有发现,列表里面有字符串,有整数,有小数呢?没错,这就是列表的包容性,什么都可以装。

那么当我们把元素放入列表之后,做什么呢?当然是提取出来。比如我想提取第一个该怎么写呢?

提取单个元素

公式是:列表名后加带偏移量的中括号。

  1. list=['小明',18,1.70]
  2. # 正值索引 打印列表第一个元素,从0开始
  3. print(list[0])
  4. # 负值索引 打印列表倒数第一个元素
  5. print(list[-1])

什么是偏移量呢?简单理解就是从左到右的顺序,并且python是从0开始,也就是第一个 “小明”是0。所以提取小明就是 list[0],第二个18就是 list[1]

如果遇到多层嵌套,提取方式就像剥洋葱,从外到内,比如下面我想提取小红这个元素,就要看小红在下面列表的第一个列表里的第二个。所以就是name[0][1]

  1. # 多层嵌套使用下面这种换行写法,看起来更清晰
  2. name = [
  3. ['小明','小红','小刚','小美'],
  4. ['小强','小兰','小伟','小芳']
  5. ]
  6. print(name[0][1]) #取第一个列表的第二个值,结果小红

提取多个元素(切片)

这里我们要引入另外一个名字叫【切片】,什么是切片呢?可以理解为一个刀片切开了列表,而这个刀片是冒号。记住口诀,左+1取 到 右不取,怎么理解呢?比如下面案例里的[1,4],套用我们的公式就是取值范围就是第二到第四。

切片运算符的语法是[start: end: step],其中,start表示开始索引,end表示结束索引,step表示步长(切片间隔,可以是正数,也可以是负数,不填则默认为1,步长为2,间隔就是1)

他们三个的关系是 [start+1: end step-1],比如[0: 5: 2],那么取值范围

  1. list = [5,6,7,8,9]
  2. print(list[:])
  3. # 所有:打印出[5,6,7,8,9]
  4. print(list[2:])
  5. # 从第3个开始后面所有:打印出[7,8,9]
  6. print(list[:3])
  7. # 第3个开始到前面所有:打印出[5,6,7]
  8. print(list[1:4])
  9. # 代表第2个到第4个:打印出[6,7,8]
  10. print(list[0:-2])
  11. # 代表第一个到倒数第二个,左取右不取结果就是 [5,6,7]
  12. # 加上步长 ——————————————————————————————————————————
  13. print(list[0:4:2])
  14. # 代表第1个到第4个,步长为2,也就是中间隔一个进行取值:打印出[5,7]
  15. print(list[::2])
  16. # 两个冒号代表全取,步长2代表隔一个,打印出[5,7,9]
  17. print(list[::-1])
  18. # 两个冒号代表全取,步长-1代表倒叙,打印出[9, 8, 7, 6, 5]
  19. # 负数时候注意 ——————————————————————————————————————————
  20. print(list[-1:-4])
  21. # 取值是从左往右,所以这里的结果是空,-1是最后一位数并且不取左边的值,往右没有值
  22. print(list[-4:-1])
  23. # 结果 [6, 7, 8]

方法与函数

在介绍添加/删除列表之前,我先补充一个知识点来作为铺垫,让你更好的理解下面内容。

我们来看下《Python编程 从入门到实践》里是如何解释的:拿下面案例的第3行举例

在print() 语句中,方法title() 出现在这个变量的后面。方法是Python可对数据执行的操作。在name.title() 中,name 后面的句点(. )让Python对变量name 执行方法title() 指定的操作。每个方法后面都跟着一对括号,这是因为方法通常需要额外的信息来完成其工作。这种信息是在括号内提供的。函数title() 不需要额外的信息,因此它后面的括号是空的。

听起来有点绕,我们直接用案例说明,仔细观察,看到他们的不同了吗?

方法是用点来使用,函数则不需要。

常用方法

  1. name = ' jiao chenglong'
  2. # title 首字母大写
  3. print(name.title())
  4. # upper 全部大写
  5. print(name.upper())
  6. # lower 全部小写
  7. print(name.lower())
  8. # strip 去除变量开头和结尾的空格 lstrip左边空格 rstrip 右边空格
  9. print('|'+name.strip()+'|')
  10. print('|'+name.lstrip()+'|')
  11. print('|'+name.rstrip()+'|')
  12. # find 找到变量的位置索引值,如果有多个会显示第一个位置,如果没找到结果是-1
  13. print(name.find("o")) # 结果是4
  14. print(name.find("A")) # 结果是-1
  15. # find 我们加上取值范围,在第一和第五个字符之间查找字母i
  16. print(name.find("i", 0, 5)) # 结果是2
  17. # replace 替换 把 o 换成 *
  18. print(name.replace("o", "*"))
  19. # replace 后面不填代表删除
  20. print(name.replace("chenglong", ""))
  21. # count子字符串出现的次数
  22. print(name.count('o')) # 结果是 2
  23. # split分割
  24. s1 = "123,056,089"
  25. a = s1.split(',') # 以 , 分割
  26. print(a) # 结果是 ['123', '056', '089']
  27. s2 = "".join(a) # 定义一个字符串(里面的空是连接符),然后把a里的值(['123', '056', '089'])提取出来
  28. print(s2) # 结果是123056089
  29. s3 = "-".join(a) # 定义一个字符串(连接符是-)
  30. print(s3) # 结果是123-056-089

他们的结构都是变量名+点+另外一个词+括号,而这个“另外一个词”我们称之为【方法】,python里面有许许多多的方法,下面我们的添加和删除用的也是方法的其中之一。

注意:下面所有的偏移量仍然是从0开始计数。新增和修改必须是数据类型一致,比如 names = [1, 2, 3],列表里面的值是整数类型,所以添加元素 names.append(2) 里面的值(2)必须也是整数类型。
**

  1. # 【新增】append() 默认添加元素到末尾————————————————————————————
  2. # 一次只能给一个参数
  3. names = [1, 2, 3]
  4. names.append(2)
  5. print(names) # 结果是[1, 2, 3, 2]
  6. # 用列表/字典可以添加多个,但是会出现俄罗斯套娃一样的多层嵌套
  7. names = [1, 2, 3]
  8. names.append([4, 5])
  9. names.append({6, 7, 8})
  10. print(names) # 结果是[1, 2, 3, [4, 5], {8, 6, 7}]
  11. # 【新增】insert() 添加元素具体的位置——————————————————————————
  12. names = [5, 6, 7, 8]
  13. names.insert(2, 0) # insert(i,x),i表示插入位置(可以是负数),x表示插入值(类型必须和列表一致)
  14. print(names) # 结果是[5, 6, 0, 7, 8]
  15. names = [5, 6, 7, 8]
  16. names.insert(-3, 0) # 先找下标-3对应的值是6,然后6的下标是1,所以相当于 insert(1,0)
  17. print(names) # 结果是[5, 0, 6, 7, 8]
  18. # 【新增】extend([新列表]) 在列表追加多个元素——————————————————————————
  19. names = [1, 2]
  20. names.extend([3, '4']) # 是列表形式,可以多种类型
  21. print(names) # 结果是[1, 2, 3, '4']
  22. # 【删除】pop() ————————————————————————————————————————————————————
  23. # 为空时默认删除(弹出)列表最后一个元素
  24. names = [11, 12, 13]
  25. hello = names.pop()
  26. print(hello) # 结果13
  27. # pop(1) 弹出列表第二个元素
  28. names = [11, 12, 13]
  29. hi = names.pop(1)
  30. print(hi) # 结果12
  31. # pop(1) 弹出列表第二个元素并把剩余的打印出来
  32. names = [11, 12, 13]
  33. names.pop(1)
  34. print(names) # 结果[11, 13]
  35. # 【删除】remove() 括号里面直接跟列表的值而非下标值,并且只能是一个值;如果匹配到多个值,则删除第一个。
  36. names = [1, 2, 3]
  37. names.remove(1) # 这里删除的是值,而非下标(偏移量)
  38. print(names) # 结果是[2, 3]
  39. # 【删除】del 列表[偏移量] 删除列表的第二位元素——————————————————————————————————
  40. names = [1, 2, 3, 4, 5, 6]
  41. del names[1] # 删除第二个数字2 此时结果是[1, 3, 4, 5, 6]
  42. del names[2:] # 再使用切片,删除多个
  43. print(names) # 结果是[1, 3]
  44. # 【修改】修改元素是给元素直接赋值即可——————————————————————————
  45. names = [10, 20, 30]
  46. names[0] = 80
  47. print(names) # 结果是[80, 20, 30]
  48. names = [10, 20, 30]
  49. names[0], names[1] = names[1], names[0] # 互换位置
  50. print(names) # 结果是[20, 10, 30]
  51. # 【排序】sort() ————————————————————————————————————————————————————
  52. mylist = [1, 3, 2, 5, 4]
  53. # 使用方法sort()对列表进行正排序(永久性)
  54. mylist.sort()
  55. print(mylist) # 结果是 [1, 2, 3, 4, 5]
  56. # 使用 #函数# sorted()对列表进行正排序(临时性)
  57. print(sorted(mylist)) # 结果是 [1, 3, 2, 5, 4] 重新输出发现排序没变
  58. # 可以给sort()方法传递参数 reverse=true
  59. mylist.sort(reverse=True)
  60. print(mylist) # 结果是 [5, 4, 3, 2, 1]
  61. mylist.sort(reverse=False)
  62. print(mylist) # 结果是 [1, 2, 3, 4, 5]
  63. # 【排序】reverse() ————————————————————————————————————————————————————
  64. # 使用方法reverse()反转排序,是反转 不是按照字母反转,类似于 list[::-1]
  65. cars = [1, 2, 3, 4, 5]
  66. cars.reverse()
  67. print(cars) # [5, 4, 3, 2, 1]
  68. # print(cars[::-1])


pop是暂时弹出并调用这个元素,del是直接删除列表的元素,无法后续使用。**

函数

注意:同一类型从能进行排序,比如 list=[0,’1’],这样的不同类型,是不可以进行排序的。

  1. fruit = "Hello,world"
  2. print(len(fruit)) # len获取字符串长度,结果是11
  3. print(len(fruit)-1) # 获取最后一个值的下标值(获取总长度,然后减去一) 结果是11
  4. print(fruit[10]) # 打印第11个元素的值,结果是d
  5. print(fruit.index('w')) # 获取元素w的下标值,结果是6
  6. print(fruit[-1]) # 获取最后一个元素的值 结果是d
  7. # in or not in 结果是布尔值
  8. print("ao" in name)
  9. print("ao" not in name)
  10. # 使用 #函数# sorted()对列表进行排序(临时性)
  11. cars = ['1', 'A', 'a', '05', '4']
  12. print(sorted(cars)) # 结果是 ['05', '1', '4', 'A', 'a']
  13. print(cars) # 结果是 ['1', 'A', 'a', '05', '4'] 重新输出发现排序没变
  14. print(min(cars)) # 结果是05
  15. print(max(cars)) # 结果是a

数据类型:字典

字典和列表一样,都是元素,不过字典的元素是由键和值组成,并用大括号{}括起来。

  1. list ={'小明':90,'小李':86}

这里面的小明就是【键】,而对应的数值就是【值】,把他们两个用冒号连接起来就叫【键值对】,上面有两个键值对 小明:90和小李:86

需要注意的是:字典里的【键】是唯一的不能重复的,但是【值】是可以重复。因为对应键里面的数值后续调用都是取的键,重复了程序是无法调取的。列表用偏移量,字典用键。

  1. #列表用偏移值
  2. list =['小明:90','小李:86']
  3. print(list[0]) #结果小明:90
  4. #字典用键
  5. list ={'小明':90,'小李':86}
  6. print(list['小明']) #结果90

新增键值对的公式:字典名[键] = 值;删除键值对的公式:del 字典名[键]

  1. list = {'小明': 90, '小李': 86}
  2. # 增,使用键
  3. list['小黑'] = 60
  4. print(list)
  5. # 删 使用del或 pop方法,后面跟的是key
  6. list.pop('小李')
  7. print(list)
  8. # 改,使用键重新赋值
  9. list['小黑'] = 68
  10. print(list)
  11. # 查
  12. print(list['小黑']) #这种方式,如果小黑不存在,则会报错,所以我们用下面的get
  13. name = list.get("A", -1) # 找A这个键对应的值,如果没有输出-1
  14. print(name)
  15. name = list.setdefault("B", -1) # 找A这个键对应的值,如果没有输出-1,并且新增该键值对
  16. print(name)
  17. print(list)

字典和列表的不同点:列表有明确的顺序,所以取值用的偏移量;字典没有顺序,所以取值用的是唯一的键。

  1. s = {'小明': 90, '小李': 86, '小红': 68}
  2. for i in s: # 遍历字典中的键和值
  3. print(f"key={i},values={s[i]}")
  4. for k in s.keys(): # 遍历字典中的键
  5. print(k)
  6. for v in s.values(): # 遍历字典中的值
  7. print(v)
  8. for k, v in s.items(): # 遍历字典中的键和值
  9. print(f"key={k},values={v}")
  10. l = list(s.keys()) # 把键转化为列表
  11. print(l)
  12. t = tuple(s.values()) # 把值转化为元祖
  13. print(t)

和list比较,dict有以下几个特点:查找和插入的速度极快,不会随着key的增加而变慢;需要占用大量的内存,内存浪费多。所以,dict是用空间来换取时间的一种方法。请一定要记得,dict的key必须是不可变对象。这也是为什么他查询更快的原因。

str是不变对象,而list是可变对象。对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

  1. # 可变的列表
  2. a = ['c', 'b', 'a']
  3. a.sort()
  4. print(a) # ['a', 'b', 'c']
  5. # 不可变的字符串
  6. b = 'abc'
  7. print(b.replace('a', 'A')) # Abc,也可以理解为临时修改
  8. print(b) # abc

遍历字典

  1. config = {
  2. 'ip': '192.168.1.1',
  3. 'port': '8080',
  4. 'name': 'jiao',
  5. # 字典
  6. 'options': {
  7. 'encode': 'utf-8',
  8. 'timeout': '300',
  9. },
  10. # 列表
  11. 'driver': ['pgsql', 'npgsql']
  12. }
  13. print(config['options']) # 打印字典config里的字典
  14. print(config['driver']) # 打印字典config里的列表
  15. # 遍历所有属性
  16. for key, Val in config.items():
  17. print(key, '=', Val)
  18. # 遍历所有的key(常用)
  19. for key in config.keys():
  20. print('key =', key)
  21. # 遍历所有的value(少用)
  22. for Val in config.values():
  23. print('Val =', Val)

数据类型:元组

另外这里延展一个知识点【元组】(tuple)。元组和列表很相似,不过它是用小括号来包的。元组和列表都是序列,提取的方式也是偏移量,也支持任意的嵌套,不同的是元组不可修改,没有append(),insert()这样的方法!

不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。

  1. #元组用的是小括号
  2. list =('小明','小李','小黑')
  3. print(list[2])
  4. #多层嵌套,用中括号和逗号分开
  5. list = [('小明','小李'),('小黑','小兰')]
  6. print(list[1][0])

列表推导式

它的结构是 [表达式 for 变量 in 列表 if 筛选条件] ,外面的大括号说明生成的直接是列表形式,所以不需要新建空列表和添加列表的动作。

  1. list1 = [1, 2, 3]
  2. list2 = []
  3. # 将列表里的值x2的常规用法
  4. for i in range(3):
  5. list2.append(list1[i]*2) # 注意这里用的是list[]下标,是用里面的值x2 不是列表x2
  6. print(list2) # [2, 4, 6]
  7. # 使用推导式将列表里的值x2的写法
  8. list3 = [i*2 for i in list2] # [表达式 for 变量 in 列表]
  9. print(list3) # [4, 8, 12]
  10. # 加入筛选条件 ——————————————————————————————————
  11. # 常规写法
  12. list4 = []
  13. for i in range(10):
  14. if i % 2 == 0:
  15. list4.append(i*2)
  16. print(list4) #[0, 4, 8, 12, 16]
  17. # 推导式写法
  18. list5 = [i*2 for i in range(10) if i % 2 == 0] # 如果能被2整除,那么就 x2
  19. print(list5) #[0, 4, 8, 12, 16]
  20. # 转化类型 ———————————————————————————————————
  21. list6 = [5, 6, 7, 8]
  22. list7 = [str(i) for i in list6 if i >= 7]
  23. print(list7) # ['7', '8']
  24. list8 = ['hello', 'a', '123']
  25. list9 = [i.title() for i in list8] #使用方法可以对遍历的值进行修改
  26. print(list9) # ['Hello', 'A', '123']
  27. # 放在表达式里打印结果 ———————————————————————————————————
  28. list10 = range(10)
  29. [print(i) for i in list10]