[关闭]
@pluto-the-lost 2020-10-16T03:18:08.000000Z 字数 4745 阅读 35

PyFrom0 - 2. Python的基本数据结构

从零开始的Python


这里只说各种python里的数据结构和他们的用法,如果想了解底层是怎么回事,在这里:数据结构基础知识

1. python是一种动态语言

(这节看不懂可以跳过)

动态语言意思是“变量和数据类型不绑定,可以动态切换”。反过来说其他的一些语言,一个变量生成的时候是什么数据类型,它一辈子就只能是这个类型。举个例子

  1. # 这是python代码
  2. a = 1
  3. a = '1' # 先定义a为数字,再改成字符串,这是可以的
  4. print(a) # 会输出'1'
  1. # 这是C++代码
  2. int main(){
  3. int a=1; # 生成a的时候,它是数字
  4. a = '1';
  5. cout << a; # 会输出49,这是字符'1'的ascii码,程序自动把字符'1'转成了数字
  6. char b='1';
  7. cout << b; # 会输出'1'
  8. }
  9. # 注:cout就是c++里的print

所以python还是很方便的

2. python里的基础数据类型

2.1 基础类型的生成方式

和前置课程里说的一样,python里的基础数据类型也是这么几个:整数、浮点数、字符串、布尔值、空值

(字符和指针被藏起来了,不让程序员直接看见,但是很多高级数据结构会间接地用到它们)

下面是生成这些数据类型的方法

  1. a = 1 # 整数
  2. b = 1.0 # 浮点数,也可以用“b = float(a)”
  3. c = '123' # 字符串,单双引号都可以,但是要配对
  4. d = True # 布尔值,假是False
  5. e = None # 空值

基础变量生成
注意空值是不会显示在变量观察区的

2.2 基础类型的内建函数

内建函数的意思是类自带的函数,在下一个篇章会有详细介绍(现在还没有,不用点过去了)。现在可以暂时理解成这些数据天生具有的一些功能,就像人天生就会呼吸

调用类的某个内建函数,要通过这个数据类型的一个变量,在变量名后面打上小数点,再接上内建函数名和必须的参数。在一般的IDE中,打上小数点再按Tab,就能看到都有哪些函数了

内建函数

显然不同类型的内建函数不一样,常用的内建函数包括但不限于

  1. a = 123
  2. a.bit_length() # 返回变量a占了多少比特的内存空间,这里返回7
  3. # bit_length() 这个函数每个数据类型都会有,后面就不说了
  1. a = 1.5
  2. a.is_integer() # 判断a是不是整数,这里返回False,如果a=1.0就返回True
  3. a.as_integer_ratio() # 把a表示成两个整数的商,这里返回(3,2)
  1. # 这个可丰富了,做好心理准备
  2. a = 'abc'
  3. a.capitalize() # 首字母大写,这里返回'Abc'
  4. a.casefold() # 返回全小写的字符串
  5. a.count('a') # 数字符串里出现某个子串的次数
  6. a.find('a') # 返回字符串里出现某个字串的位置
  7. a.isdigit() # 判断字符串是不是完全由数字组成,包含小数点也不行
  8. a.islower() # 判断字符串是不是完全由小写字母组成,相对还有isupper()
  9. a.strip() # 去掉字符串前后的空格
  10. a.startswith('a') #判断a是不是由某个字串开头的,对应的还有endswith()

字符串还有很多很多的内建函数,可以实现相当丰富的操作,具体可见python字符串内置函数

2.3 字符串

字符串可以说是python里最重要的数据类型之一了。python的常用场景是数据分析、网络爬虫、机器学习、网页开发等领域,几乎全部要和大量字符串打交道。比如

对字符串的基础操作通常包括【去除杂字符、分割和拼接、查找和替换、编码和解码】等,其中最有技术难度的是“查找”

虽然找一个特定的字串很容易,但是通常我们的需求都是【寻找符合某种模式的字串】。比如网页爬虫拿到一个html,我想知道这个网页都链接到了哪些其它网页,那么我是想在html文件中寻找“以https://”开头,以“.com/.cn/.en/.us/.org/...”等结尾的子串

这个功能的实现并不简单,需要用到“正则表达式”。后面的篇章会详细介绍

## 3. python自带的复合数据类型
就像在前置课程里说的,所有其它类型都是上述基础类型的结合、变换和应用。这里只介绍一些最重要的

3.1 元组和列表

(不看也行:元组是数组,列表是动态数组,有关知识在这里

  1. # 生成元组
  2. a = (1,2,3,4,5)
  3. b = (1,'2',True) # 元组的元素可以是不同数据类型
  4. c = (a,b) # 元组的元素甚至可以是元组
  5. d = a + b # 会得到(1,2,3,4,5,1,'2',True),把两个元组拼在一起
  6. e = () # 空的元组也可以噢,更建议使用e = tuple()生成空元组
  7. # 调用元组的元素,也叫【索引】
  8. a[0] # 返回1,python里的索引都是从0开始的,所以a[0]是取a元组的第一个元素
  9. a[1:4] # 返回(2,3,4),:号表示取中间的所有元素,含头不含尾(这个设定相当坑爹)
  10. c[0][6] # c[0]返回a,再接一个[1]返回a的第二个元素,即2
  1. # 生成列表和生成元组完全一样,只是把小括号换成中括号
  2. a = [1,3,2,4,5]
  3. # 列表的索引和元组完全一样
  4. # 列表的内建函数,这可就不一样了
  5. a.append(6) # 把一个元素加在列表末尾
  6. #【注意】这个函数返回None,但是a现在变成了[1,3,2,4,5,6]
  7. a.pop() # 返回最末尾的元素6,同时把它从列表里删除
  8. #【注意】现在a又变回了[1,3,2,4,5]
  9. # 为了方便,我们之后假定每个函数作用的a一直是[1,3,2,4,5]吧
  10. a.insert(2,6) # 在idx=2的位置插入一个6,a变成[1,3,6,2,4,5]
  11. a.remove(5) # 删掉【第一个】值为5的元素,a变成[1,3,2,4]
  12. a.sort() # 从小到大排序,a变成[1,2,3,4,5]
  13. a.reverse() # 列表前后翻转,a变成[5,4,2,3,1]
  1. a = [1,2,3,4,5] # 这里换成元组(1,2,3,4,5)也是一样的
  2. # 直接遍历每个值
  3. for i in a:
  4. print(i)
  5. # 通过索引遍历
  6. for idx in range(0,len(a)): # len(a)返回5,即列表的长度,range(0,5)返回(0,1,2,3,4)
  7. print(a[idx])

为什么要用索引呢,一是有时候我们会想知道现在遍历到第几个了,二是这样可以在循环中对元素做改动。比如循环的内容可以变成"a[idx] = a[idx] + idx",这样a就会变成[1,3,5,7,9]
索引遍历

而"for i in a"那种遍历法只能看,不能改,即使你的循环内容写的是"i = i + i",a也不会变。背后的原理很复杂,涉及到传值和引用,先记住就行
迭代遍历

当然如果你不想知道遍历到了第几个,也不打算改内容,那就用第一种嘛,方便

3.2 集合和字典

不看也行:集合和字典都是哈希表,其中集合以值作为哈希函数的输入,字典以键作为哈希函数的输入)

  1. # 集合的生成
  2. a = set(['diandian', 'diandian', 'xiangxiang'])
  3. a
  4. # Out[37]: {'diandian', 'xiangxiang'}
  5. a = {'diandian', 'xiangxiang', 'xiangxiang'} # 这样也是一样的
  6. # 字符串输入就很神奇
  7. a = set('xyzxayabc')
  8. a
  9. # Out[38]: {'a', 'b', 'c', 'd', 'e', 'f'}
  10. # 集合的内建函数
  11. a = set('abcabcdef')
  12. a.add('g') # 加入一个元素
  13. a.discard('g') #删除一个元素
  14. # 集合的运算
  15. set1 = set(['a','b'])
  16. set2 = set(['b','c'])
  17. set1 & set2 # 交集,返回{'b'}
  18. set1 | set2 # 并集,返回{'a','b','c'}
  19. set1 ^ set2 # 异或,返回{'a','c'}
  20. set1 - set2 # 做差,返回{'a'}
  21. # 集合的遍历不可以用索引法,只能这样
  22. a = set('abcabcdef')
  23. for c in a:
  24. print(c)
  1. # 字典的生成和索引
  2. loveArrow = {'..':'xx', 'xx':'..'}
  3. loveArrow['..']
  4. # Out[46]: 'xx'
  5. loveArrow['xx']
  6. # Out[47]: '..'
  7. # 字典的内建函数
  8. a = {'first':'a', 'second':'b'}
  9. a['first'] = 'new value' # 修改某个值
  10. a['third'] = 'c' # 创建新的键值对(key-value pair)
  11. a.pop('third') # 根据键删除某个键值对
  12. a.keys() # 返回字典所有的键
  13. a.values() # 返回字典所有的值
  14. a.items() # 返回字典所有的键值对,以元组(key,value)的形式
  15. # 字典的遍历
  16. a = {'first':'a', 'second':'b'}
  17. # 根据键遍历
  18. for k in a:
  19. print(k)
  20. # 根据值遍历
  21. for v in a.values():
  22. print(v)
  23. # 根据键值对遍历:
  24. for k,v in a.items():
  25. print(k,v)

3.3 文件

(碰到再写吧)

4. 强制类型转换

很多数据类型储存的内容可以是一样的,只是储存数据的格式不同。针对这种情况,python提供了很方便的数据类型转换方法

  1. # 基本类型间的相互转换
  2. a = 123
  3. b = float(a) # 整数转浮点数,b是123.0
  4. c = str(a) # 整数转字符串,c是'123'
  5. d = bool(a) # 整数转布尔值,d是True,除了0以外的数字转布尔都是True
  6. e = int(c) # 字符串转整数,e是123
  7. f = int(d) # 布尔值转整数,f是1
  8. # 复合类型间的相互转换
  9. a = (1,2,3,1,2)
  10. b = list(a) # b是[1,2,3,1,2]
  11. c = set(a) # c是{1,2,3}

5. 深拷贝和浅拷贝,传值和引用

(可以先不看,现在看了也很难理解,以后写程序的时候会碰到想破脑袋也不知道怎么回事的bug,八成就是在这出了问题,到时再回来看)

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注