Python 非常适合初学者用来进入计算机编程领域。Python 属于非常高级的语言,掌握了这门高级语言,就对计算机编程的核心思想——抽象有了初步理解。如果希望继续深入学习计算机编程,可以学习 Java、C、JavaScript、Lisp 等不同类型的语言,只有多掌握不同领域的语言,有比较才更有收获。

1.1 环境准备
1.1.1 Python 安装
(1)官网下载 Python
进入官网(https://www.python.org),点击 Downloads,选择要下载的版本:

(2)安装 Python
安装时注意下图勾选部分一定要勾选:
1.1.2 安装代码编辑器 PyCharm
(1)官网下载 PyCharm
进入官网(https://www.jetbrains.com/pycharm),点击 Downloads,选择要下载的版本:

(2)安装 PyCharm
设置安装路径之后,一直点 next 即可。
1.1.3 安装 Jupyter notebook
数据分析,对我来说最好用的还是 Jupyter notebook
- Jupyter notebook :基于 web 的交互式计算环境,可以编辑易于人们阅读的文档,用于展示数据分析的过程。
观察一段 10 行 Python 代码,感受一下 Python 的风格:
# 温度转换
# TempConvert.py
TempStr = input("请输入带有符号的温度值:")
if TempStr[-1] in ['F','f']:
C = (eval(TempStr[0:-1]) - 32)/1.8
print("转换后的温度是{:.2f}C".format(C))
elif TempStr[-1] in ['C','c']:
F = 1.8*eval(TempStr[0:-1]) + 32
print("转换后的温度是{:.2f}F".format(F))
else:
print("输入格式错误!")
☎️ eval()
去掉参数最外侧引号并执行余下语句的函数,称为“评估函数”。
程序的基本编写方法:IPO
I
:Input 输入,程序的输入P
:Process 处理,程序的主要逻辑O
:Output 输出,程序的输出
编程解决问题的步骤:
- (1)分析问题:分析问题的计算部分,想清楚
- (2)划分边界:划分问题的功能边界,规划 IPO
- (3)设计算法:设计问题的求解算法,关注算法
- (4)编写程序:编写问题的计算程序,编程序
- (5)调试测试:调试程序使正确运行,运行调试
- (6)升级维护:适应问题的升级维护,更新完善
1.2 第一个 Python 程序
1.2.1 HelloWorld
创建第一个项目 HelloWorld --> 创建文件 app.py --> 写入代码:
print("HelloWorld")
效果图:


- 删除
要删除 list 末尾的元素,用 pop()
方法:
classmates.pop()
要删除指定位置的元素,用 pop(i)
方法,其中 i
是索引位置:
classmates.pop(1)
效果:
- 替换
要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:
classmates[1] = 'Oliver'
Ⅱ 不可变有序列表 - 元组 tuple ( )
另一种有序列表叫元组:tuple。tuple 和 list 非常类似,但是 tuple 一旦初始化就不能修改,比如同样是列出同学的名字:
classmates = ('Michael', 'Bob', 'Tracy')
现在,classmates 这个 tuple 不能变了,它也没有 append(),insert() 这样的方法。其他获取元素的方法和 list 是一样的,你可以正常地使用 classmates[0]
,classmates[-1]
,但不能赋值成另外的元素。
!> 不可变的 tuple 有什么意义?因为 tuple 不可变,所以代码更安全。如果可能,能用 tuple 代替 list 就尽量用 tuple。
? tuple 的陷阱:当你定义一个 tuple 时,在定义的时候,tuple 的元素就必须被确定下来,比如:
t = (1, 2)
print(t) # (1, 2)
如果要定义一个空的 tuple,可以写成 ()
:
t = ()
print(t) # ()
但是,要定义一个只有 1 个元素的 tuple,如果你这么定义:
t = (1)
print(t) # 1
定义的不是 tuple,是 1
这个数!这是因为括号 ()
既可以表示 tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python 规定,这种情况下,按小括号进行计算,计算结果自然是 1
。
所以,只有 1 个元素的 tuple 定义时必须加一个逗号,
,来消除歧义:
t = (1,)
print(t) # (1,)
?> Python 在显示只有 1 个元素的 tuple 时,也会加一个逗 ,
,以免你误解成数学计算意义上的括号。
最后来看一个 “可变的” tuple :
t = ('a', 'b', ['A', 'B'])
t[2][0] = 'X'
t[2][1] = 'Y'
print(t) # ('a', 'b', ['X', 'Y'])
这个 tuple 定义的时候有 3 个元素,分别是'a'
,'b'
和一个 list。不是说 tuple 一旦定义后就不可变了吗?怎么后来又变了?
别急,我们先看看定义的时候 tuple 包含的 3 个元素:

当我们把 list 的元素 'A'
和 'B'
修改为 'X'
和 'Y'
后,tuple 变为:
表面上看,tuple 的元素确实变了,但其实变的不是 tuple 的元素,而是 list 的元素。tuple 一开始指向的 list 并没有改成别的 list,所以,⭐ tuple 所谓的 “不变” 是说,tuple 的每个元素,指向永远不变。即指向 'a'
,就不能改成指向 'b'
,指向一个 list,就不能改成指向其他对象,但指向的这个 list 本身是可变的!
理解了 “指向不变” 后,要创建一个内容也不变的 tuple 怎么做?那就必须保证 tuple 的每一个元素本身也不能变。
⑦ 字典
Ⅰ dict(key - value)
Python 内置了字典:dict 的支持,dict 全称 dictionary,在其他语言中也称为 map,使用键 - 值(key - value)存储,具有极快的查找速度。
- 创建
示例代码:学生姓名和成绩
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print(d) # {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print(d['Michael']) # 95
print(d[0]) # KeyError: 0
为什么 dict 查找速度这么快?因为 dict 的实现原理和查字典是一样的。假设字典包含了 1 万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在 list 中查找元素的方法,list 越大,查找越慢。
第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。
dict 就是第二种实现方式,给定一个名字,比如'Michael'
,dict 在内部就可以直接计算出 Michael
对应的存放成绩的 “页码”,也就是 95
这个数字存放的内存地址,直接取出来,所以速度非常快。
把数据放入 dict 的方法,除了初始化时指定外,还可以通过 key 放入:
d['Adam'] = 67
print(d['Adam']) # 67
print(d) # {'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 67}
- 判断 value 是否存在
由于一个 key 只能对应一个 value,所以,多次对一个 key 放入 value,后面的值会把前面的值冲掉:
d['Adam'] = 67
print(d['Adam']) # 67
d['Adam'] = 97
print(d['Adam']) # 97
如果 key 不存在,dict 就会报错:KeyError
。


当我们调用 a.replace('a', 'A')
时,实际上调用方法 replace
是作用在字符串对象 'abc'
上的,而这个方法虽然名字叫 replace
,但却没有改变字符串 'abc'
的内容。相反,replace
方法创建了一个新字符串 'Abc'
并返回,如果我们用变量 b
指向该新字符串,就容易理解了,变量 a
仍指向原有的字符串 'abc'
,但变量 b
却指向新字符串 'Abc'
了:
所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
!> 小结
- 使用 key - value 存储结构的 dict 在 Python 中非常有用,选择不可变对象作为 key 很重要,最常用的 key 是字符串。
- tuple 虽然是不变对象,但试试把
(1, 2, 3)
和(1, [2, 3])
放入 dict 或 set 中,就会有新发现。
1.3.3 变量与常量
① 变量
变量是用来保存和表示数据的占位符号。变量采用标识符(名字)来表示,关联标识符的过程叫命名。比如实例 1:温度转换中的 TempStr 就是变量名字。
命名规则:大小写字母、数字、下划线_
和汉字等字符及组合,且不能用数字开头
如:TempStr,Python\_Great,这是门Python好课
? 注意点:大小写敏感、首字符不能是数字、不与保留字相同。
⛳️ 拓展:保留字
保留字:被编程语言内部定义并保留使用的标识符。
- Python 语言有 33 个保留字(也叫
关键字
),比如:if、elif、else、in - 保留字是编程语言的基本单词,大小写敏感,比如:if 是保留字,If 是变量
保留字看下表:


执行b = a
,解释器创建了变量b
,并把b
指向a
指向的字符串'ABC'
:
执行a = 'XYZ'
,解释器创建了字符串'XYZ',并把a
的指向改为'XYZ'
,但b
并没有更改:

b
的结果自然是'ABC'
了。② 常量
所谓常量就是不能变的变量,比如常用的数学常数 π 就是一个常量:
PI = 3.14159265359
在 Python 中,通常用全部大写
的变量名表示常量。
但事实上 PI
仍然是一个变量,Python 根本没有任何机制保证 PI
不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量 PI
的值,也没人能拦住你。
1.3.4 字符串和编码
① 字符串编码问题
我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。
因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用 8 个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是 255(二进制 11111111 = 十进制 255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535
,4 个字节可以表示的最大整数是4294967295
。
由于计算机是美国人发明的,因此,最早只有 127 个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII
编码,比如大写字母A
的编码是65
,小写字母z
的编码是122
。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和 ASCII 编码冲突,所以,中国制定了GB2312
编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS
里,韩国把韩文编到Euc-kr
里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode 应运而生。Unicode 把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode 标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要 4 个字节)。现代操作系统和大多数编程语言都直接支持 Unicode。
? 现在,捋一捋 ASCII 编码和 Unicode 编码的区别:ASCII 编码是 1 个字节,而 Unicode 编码通常是 2 个字节。
- 字母
A
用 ASCII 编码是十进制的65
,二进制的01000001
; - 字符
0
用 ASCII 编码是十进制的48
,二进制的00110000
,注意字符'0'
和整数0
是不同的; - 汉字
中
已经超出了 ASCII 编码的范围,用 Unicode 编码是十进制的20013
,二进制的01001110 00101101
。
你可以猜测,如果把 ASCII 编码的A
用 Unicode 编码,只需要在前面补 0 就可以,因此,A
的 Unicode 编码是00000000 01000001
。
新的问题又出现了:如果统一成 Unicode 编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用 Unicode 编码比 ASCII 编码需要多一倍
的存储空间
,在存储和传输上就十分不划算。
所以,本着节约的精神,又出现了把 Unicode 编码转化为 “可变长编码” 的UTF-8
编码。UTF-8 编码把一个 Unicode 字符根据不同的数字大小编码成 1-6 个字节,常用的英文字母被编码成 1 个字节,汉字通常是 3 个字节,只有很生僻的字符才会被编码成 4-6 个字节。如果你要传输的文本包含大量英文字符,用 UTF-8 编码就能节省空间:

从上面的表格还可以发现,UTF-8 编码有一个额外的好处,就是 ASCII 编码实际上可以被看成是 UTF-8 编码的一部分,所以,大量只支持 ASCII 编码的历史遗留软件可以在 UTF-8 编码下继续工作。
搞清楚了 ASCII、Unicode 和 UTF-8 的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:
? 在计算机内存中,统一使用 Unicode 编码,当需要保存到硬盘或者需要传输的时候,就转换为 UTF-8 编码。
用记事本编辑的时候,从文件读取的 UTF-8 字符被转换为 Unicode 字符到内存里,编辑完成后,保存的时候再把 Unicode 转换为 UTF-8 保存到文件:
浏览网页的时候,服务器会把动态生成的 Unicode 内容转换为 UTF-8 再传输到浏览器:


如果bytes
中只有一小部分无效的字节,可以传入errors='ignore'
忽略错误的字节:
要计算str
包含多少个字符,可以用len()
函数:
print(len('ABC')) # 3
print(len('中文')) # 2
len()
函数计算的是str
的字符数,如果换成bytes
,len()
函数就计算字节数:
print(len(b'ABC')) # 3
print(len(b'\xe4\xb8\xad\xe6\x96\x87')) # 6
print(len('中文'.encode('utf-8'))) # 6
可见,1 个中文字符经过 UTF-8 编码后通常会占用 3 个字节,而 1 个英文字符只占用 1 个字节。
? 在操作字符串时,我们经常遇到
str
和bytes
的互相转换。为了避免乱码问题,应当始终坚持使用 UTF-8 编码对str
和bytes
进行转换。由于 Python 源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为 UTF-8 编码。当 Python 解释器读取源代码时,为了让它按 UTF-8 编码读取,我们通常在文件开头写上这两行:
#!/usr/bin/env python3 # -*- coding: utf-8 -*-
第一行注释是为了告诉 Linux/OS X 系统,这是一个 Python 可执行程序,Windows 系统会忽略这个注释;
第二行注释是为了告诉 Python 解释器,按照 UTF-8 编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
③ 格式化
最后一个常见的问题是如何输出格式化的字符串
。我们经常会输出类似'亲爱的 xxx 你好!你 xx 月的话费是 xx,余额是 xx'
之类的字符串,而 xxx 的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式。
