大纲
思维导图:https://www.processon.com/view/link/601ebbfb5653bb053e353ab9
1. 基本数据类型
整型
首先是整型,也就是整数,它的表示和数学上的表示一致,例如:0
、100
、-100
# 定义了⼀个变量a,赋值为1,然后打印它
a = 1
print(a)
1
当遇到长整数时,为了让可读性更⾼,我们可以用下划线连接
# 比如一百万,我们可以这么写
1_000_000
1000000
这就等价于没有下划线的一百万,这么写,是不是让⼤家⼀眼就能看出,它是⼀百万呢?
浮点型
然后是浮点型,浮点型就是小数,比如1.1
、2.2
、-3.3
、1.0
之类的
# 定义一个浮点型,然后再打印它
a = 1.1
print(a)
1.1
大的浮点型可以用科学计数法表示,例如:1e4
等价于 10000
,1.1e-4
等价于 0.00011
1e4
10000.0
1.1e-4
0.00011
布尔型
接下来我们看布尔型,即 True
或者 False
# 定义一个变量为True,然后打印它
a = True
print(a)
True
布尔类型存在三种运算,与
或
非
,分别使用and
or
not
关键字
# 使用and,表示与
True and False
False
# 使用or,表示或
True or False
True
# 使用not,表示非
not a
False
运算符
接下来我们看 前面这些类型 的运算符,包括:
- 算数运算符:加(
+
)、减(-
)、乘(*
)、除(/
)、整除(//
)、取余(%
)、幂(**
) - 比较运算符:等于(
==
)、不等于(!=
)、大于(>
)、小于(<
)、大于等于(>=
)、小于等于(<=
),返回布尔值(True
或False
)
# 加减乘除 运算符
print(1+1)
print(1-1)
print(1*2)
print(2/2, 3/2) # 注意,整数除法默认都返回浮点数,即使能整除
2
0
2
1.0 1.5
# 整除 取余 幂 运算符
print(3//2) # 整除使用两个撇来表示
print(5%2) # 用百分号表示取余
print(2**3) # 两个星号表示幂
1
1
8
# 比较运算符,返回布尔值
print(1==2)
print(1!=2)
print(3>1)
print(3<1)
print(4>=3)
print(4<=3)
False
True
True
False
True
False
# 连续比较
1 < 3 < 4 # 等价于 1 < 3 and 3 < 4
True
字符串
接下来我们看字符串,所谓字符串,就使用 单引号
或者 双引号
或者 三引号
括起来的文本,比如:
s1 = 'hello'
s2 = "hello"
s3 = """hello"""
print(s1, s2, s3)
hello hello hello
三引号
经常用来表示跨行文本,比如:
"""hello
... hello"""
‘hello\nhello’
我们注意 两个hello
中间的 \n
换行
然后是转义字符,使用反斜杠
来表示转义,于是:\n
表示换行
# 打印一个换行文本
print('hello\nhello')
hello
hello
\t
表示Tab,\\
表示字符\
# 打印一个字符串
print('hello\tworld \\ hello\tworld')
hello world \ hello world
当使用r
来修饰字符串时,r表示raw,表示使用原始字符串,即不转义
# 打印raw字符串
print(r'hello\tworld \\ hello\tworld') # 不转义任何字符
hello\tworld \ hello\tworld
接下来我们看字符串的运算符,包括:
- 拼接(
+
)、重复(*
)、索引([]
)、切片([:]
)、是否在(in
)
# 字符串拼接
'ab' + 'cde' # 返回一个新的字符串
‘abcde’
# 字符串重复
'ab'*10 # ab重复10次
‘abababababababababab’
# 使用[]索引字符串
s = 'abcdefg'
print(s[0]) # 索引第0个字符
print(s[2]) # 索引第2个字符
print(s[-1]) # 索引倒数第1个字符
a
c
g
# 使用[],声明start, end,切片字符串
print(s[0:3]) # 切片第0到第3个字符(不包括第3)
print(s[:3]) # 切片从头到第3个字符(start为0时,可以省略)
print(s[3:]) # 切片从第3个字符到结束(end为结束时,可以省了)
abc
abc
defg
# 判断字符串a是否为字符串b的一部分,使用关键字in
'bc' in 'abcde' # 判断 字符串'bc' 是否是字符串'abcde' 的一部分
True
然后我们看字符串的格式化输出,格式化字符串使用%s
,格式化整数使用%d
,格式化浮点数使用%f
# 格式化输出
'我叫%s,年龄%d, 体重%.2f' % ('老王', 18, 50.5)
‘我叫老王,年龄18, 体重50.50’
# 使用format函数实现格式化输出
'我叫{:s},年龄{:d}, 体重{:.2f}'.format('老王', 18, 50.5)
‘我叫老王,年龄18, 体重50.50’
# {}内部一般省略,这适合任意类型的格式化
'我叫{},年龄{}, 体重{}'.format('老王', 18, 50.5)
‘我叫老王,年龄18, 体重50.5’
接下来我们看看字符串的内建函数,这些都是我们未来经常会用到的:
- 首字符大写(
capitalize
) - 以子串结尾(
endswith
)、以子串开头(startswith
) - 是否是数字(
isdigit
) - 小写化(
lower
) - 去掉两端的空白字符(
strip
) - 替换(
replace
) - 合并(
join
) - 字符串长度(
len
)
# 定义演示字符串
s = 'hello laowang'
# 首字母大写字符串
s.capitalize()
‘Hello laowang’
# 判断是否以某个子串结尾
print(s.endswith('laowang')) # 判断是否以laowang结尾
print(s.endswith('lao')) # 判断是否以lao结尾
True
False
# 判断是否以某个子串开头
s.startswith('hello')
True
# 判断字符串是否是数字
print(s.isdigit())
print('123'.isdigit())
False
True
# 字符串小写化
'HEllo'.lower()
‘hello’
# 去掉两端空白字符(\t \n 空格 \r 等)
'\nhello\t '.strip()
‘hello’
# 替换子串
s.replace('laowang', 'world')
‘hello world’
# 字符串join
' '.join(['1', '2', '3']) # 数组元素用空格合并起来
‘1 2 3’
# 打印字符串的长度
len(s)
13
还有一些字符串函数我这里没有讲到,大家可以点击这个链接 Python3字符串 ,人家整理得挺好的,大家可以收藏下,需要时 可以点击左侧相关内容去查,
它整理的比较全,当然最标准的做法 是去python官网查,不过国内访问起来比较慢,体验不怎么友好。
类型转换
到这里,基础数据类型已经讲完,我们接下来讲一讲类型转换,包括:
- 使用内建函数显式转换:
int()
、float()
、bool()
、str()
- 布尔运算符的隐式转换:比如:
not 1
、0 or 1
,一般情况下,[]
{}
()
''
set()
0
None
都被默认转换为False
,其余会被转换为True
;
# 显示转换
print(int(1.1)) # 使用int()函数,将浮点数转为整型
print(float(1)) # 使用float()函数,将整数转为float
print(bool(0)) # 使用bool()函数,将整数转为布尔值
print(bool(1)) # 使用bool()函数,将整数转为布尔值
print(str(1)) # 使用str()函数,将整数转为字符串
print(str(1.1)) # 使用str()函数,将浮点数转为字符串
print(str(True)) # 使用str()函数,将布尔值转为字符串
1
1.0
False
True
1
1.1
True
# 隐式转换
print(not 1) # 隐式转换,将整数1转换为True
print(bool(0 or 1)) # 隐式转换,将整数0转换为False,将整数1转换为True
False
True
2. 集合类型
在Python里,集合类型用来存放多个不同类型的对象。常见的集合类型包括:列表(list)、元组(tuple)、集合(set)、字典(dict)
列表
列表是一种有序集合,元素可以是任意类型,比如:[1, 2., '3', True]
# 通过[],定义一个列表
l = [1, 2., '3', True]
列表的常见操作:
- 索引(
[]
)、切片([:]
) - 修改(
=
) - 拼接(
+
)、 - 复制(
*
)、 - 迭代(
for
)、 - 检查元素是否存在(
in
)
# 索引和切片
print(l[0], l[-1]) # 打印第0个元素,倒数第1个元素
print(l[1:3]) # 打印第1到第3个元素
1 True
[2.0, ‘3’]
# 修改元素
l[-1] = 4 # 修改最后一个元素为4
l # 打印l
[1, 2.0, ‘3’, 4]
# 列表拼接
l + ['a', 'b'] # 通过+,将两个列表拼接起来,获得一个新的列表
[1, 2.0, ‘3’, 4, ‘a’, ‘b’]
# 列表复制
l * 3 # 通过*,将原始列表l复制3次,获得一个新的列表
[1, 2.0, ‘3’, 4, 1, 2.0, ‘3’, 4, 1, 2.0, ‘3’, 4]
# 列表迭代
for i in l: # 通过for循环,迭代列表
print(i)
1
2.0
3
4
# 检查元素是否存在
print(1 in l) # 检查1是否在列表l中
print(6 in l) # 检查6是否在列表l中
True
False
除此之外,列表还有一些常见的编辑操作,比如:
- 追加元素到尾部(
append
) - 插入元素到特定位置(
insert
) - 删除特定的元素(
remove
) - 弹出尾部元素(
pop
) - 合并两个列表(
extend
) - 反转(
reverse
) - 排序(
sort
)
# 打印当前列表
l
[1, 2.0, ‘3’, 4]
# 追加元素
l.append(5) # 在列表的最后,追加元素5
l
[1, 2.0, ‘3’, 4, 5]
# 插入元素
l.insert(0, 0) # 在列表的0位置,插入元素0
l
[0, 1, 2.0, ‘3’, 4, 5]
# 删除元素
l.remove(5) # 删除值为5的元素
l
[0, 1, 2.0, ‘3’, 4]
# 弹出尾部元素
l.pop() # 弹出尾部最后一个元素
l
[0, 1, 2.0, ‘3’]
# 合并两个列表
l.extend([4, 5]) # 将列表[4, 5]合并到l中
l
[0, 1, 2.0, ‘3’, 4, 5]
使用extend合并两个列表,区别于我们上面讲的列表拼接+
。虽然两个都是合并列表,
- 但extend是改第一个列表,是原地操作;
- 拼接是原始列表都不变,返回一个新的列表;
# 列表反转
l.reverse() # 反转列表,原地操作
l
[5, 4, ‘3’, 2.0, 1, 0]
# 列表排序
#l.sort() # 直接应用在l上,存在字符串'3',报错
l = [1, 3, 2] # 定义一个均为数字的新列表
l.sort() # 排序列表,默认从小到大,原地操作
l
[1, 2, 3]
我们还可以使用内建函数对列表进行操作,比如:
- 列表长度(len)
- 最大值(max)、最小值(min)
- 转换(list)
# 打印当前列表l
l
[1, 2, 3]
len(l) # 打印列表长度
3
max(l) # 打印列表l中的最大值
3
min(l) # 打印列表l中的最小值
1
list('123') # 将一个字符串转为列表
[‘1’, ‘2’, ‘3’]
关于列表,最后我们看一下列表解析式,它仅通过一行,迭代序列生成一个列表,
# 打印当前列表
l
[1, 2, 3]
# 使用列表解析式,对l中每个元素转换为字符串,获得一个新列表
[str(i) for i in l]
[‘1’, ‘2’, ‘3’]
# 使用列表解析式,对l中元素进行过滤,只保留大于等于2的元素
[i for i in l if i >= 2]
[2, 3]
更详细的 函数介绍和说明 参考这里的链接 Python3 列表。
元组
元组和列表非常类似,但是不能修改,比如:(1, 2., '3', True)
# 定义一个元祖
t = (1, 2., '3', True)
t
(1, 2.0, ‘3’, True)
# 尝试修改元组,报错
#t[0] = 0
# 元组的定义也可以不使用()
t = 1, 2., '3', True
t
(1, 2.0, ‘3’, True)
元组的常见操作和列表非常类似,它可以 索引、切片、拼接、复制、迭代、判断元素是否存在 等,但是它不能被修改,也就是说它不支持所有的编辑操作。
因为与列表过于相似,我这里不再演示。更详细的内容可以参考 Python3 元组
集合
接下来我们看集合,集合就是无序的、不重复的元素集,我们可以用大括号来定义一个集合,{1, 2}
,也可以用 set()
函数 生成一个空集合。
# 生成集合
s = {1, 2} # 通过大括号定义集合
s
{1, 2}
s = set() # 通过set函数生成一个空的集合
s
set()
# 但是请注意,空的大括号 {},定义的并不是集合,而是我们后面要讲的字典
type({}) # 通过type,打印 {} 的类型
dict
# 定义集合
s = {1, 2, 3, 4}
常见集合操作:迭代(for
)、元素是否存在(in
)
# 使用for,迭代集合元素
for e in s:
print(e)
1
2
3
4
# 判断元素是否在集合里
print(1 in s)
print(5 in s)
True
False
我们来看下集合的编辑操作,包括:添加元素(add
)、删除元素(remove
)、清空(clear
)
# 打印当前集合
s
{1, 2, 3, 4}
# 添加元素
s.add(5) # 通过add,添加元素5
print(s)
s.add(4) # 通过add,再次添加元素4
print(s)
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
# 删除元素
s.remove(5) # 通过remove,删除元素5
s
{1, 2, 3, 4}
# 清空元素
s.clear() # 通过clear,清空集合
s
set()
跟数学上的集合一样,我们的集合也支持常见的集合操作:
- 交集(
&
)、并集(|
)、差集(-
)、对称差(^
)
# 定义两个集合
s1 = {1, 2, 3}
s2 = {2, 3, 4}
# 集合交
s1 & s2
{2, 3}
# 集合并
s1 | s2
{1, 2, 3, 4}
# 集合差
s1 - s2 # 通过-实现集合减,等价于s1 - (s1 & s2)
{1}
# 对称差(在集合1 或者 在集合2 中,但是不同时在集合1 2中的元素)
s1 ^ s2 # 通过^实现对称差,等价于 (s1 | s2) - (s1 & s2)
{1, 4}
内建函数也可以操作集合,比如:
- 获得集合的长度(
len
) - 获得集合中的最大值(
max
) - 获得集合中的最小值(
min
) - 使用set函数将序列转化为集合(
set
)
这里和列表很类似,就不演示了。
列表有 列表解析式,集合也存在 集合解析式,即单行迭代序列 生成一个集合
# 使用集合解析式,迭代列表,生成一个集合
{str(e) for e in [1,2,3]}
{‘1’, ‘2’, ‘3’}
更详细的内容可以参考 Python3 集合
字典
最后我们看字典dict,字典是用来存储key value对的集合,key不能重复,可以用大括号来构造一个字典
# 定义字典
d = {'a': 1, 'b': 2, 'c': 3}
字典的常见操作:
- 迭代(
for
)、元素是否存在(in
)、访问([]
)
# 通过for循环,迭代字典的key
for key in d:
print(key) # 打印key
a
b
c
# 判断元素是否存在
1 in d # 使用in
False
# 访问某个key
d['a'] # 根据key为'a',访问其value
1
# 访问失败,会报KeyError错
#d['d']
字典常见的编辑操作:
- 修改(
[]=
)、删除(del []
)、添加([]=
)
# 打印当前字典
d
{‘a’: 1, ‘b’: 2, ‘c’: 3}
# 修改某个key
d['a'] = 11 # 修改key为'a'的元素的value为11
d
{‘a’: 11, ‘b’: 2, ‘c’: 3}
# 删除某个key
del d['a'] # 删除key为'a'的元素
d
{‘b’: 2, ‘c’: 3}
# 添加元素
d['d'] = 4 # 添加key为'd',value为4的元素
d
{‘b’: 2, ‘c’: 3, ‘d’: 4}
字典常见的函数操作:
- 指定默认值的访问(get)
- 获取所有的key(keys)
- 获取所有的value(values)
- 获取所有key-value对(items)
- 清空(clear)
# 打印当前的字典d
d
{‘b’: 2, ‘c’: 3, ‘d’: 4}
# 访问
print(d.get('b')) # 通过get方法,访问字典中存在的key,返回其对应的value
print(d.get('e')) # 通过get方法,访问字典中不存在的key,返回None
print(d.get('e', 'empty')) # 通过get方法,访问字典中不存在的key,并指定不存在时,返回默认值为empty
2
None
empty
# 获取所有的key
d.keys()
dict_keys([‘b’, ‘c’, ‘d’])
# 获取所有的value
d.values()
dict_values([2, 3, 4])
# 获取所有的key value对
d.items()
dict_items([(‘b’, 2), (‘c’, 3), (‘d’, 4)])
# 清空字典
d.clear()
d
{}
更详细的内容可以参考 Python3 字典
实践经验
这里有几个实践经验,大家可以注意下:
set
经常被用来对序列去重,因为集合是没有重复元素的;
l = [1, 2, 2, 3, 1, 2]
set(l)
{1, 2, 3}
- 判断元素是否存在时,集合比列表速度要快很多,尤其是数据量很大时;
# 生成一个10万个元素的列表和集合
from random import sample # 从random包里import随机采样函数sample
l = sample(range(1_000_000), 100_000) # 从0到100万,随机采样10万个整数,获得一个列表l
s = set(l) # 根据列表l,生成集合s
# 判断元素是否存在
import time
# 计算列表耗时
init_time = time.time()
print(1588 in l)
print(' {:.6}'.format(time.time()-init_time))
# 计算集合耗时
init_time = time.time()
print(1588 in s)
print('set cost time: {:.6}s'.format(time.time()-init_time))
False
0.0207155
False
set cost time: 0.000999689s
- 列表解析式的速度比for循环更快,实践中推荐优先使用;
# 生成一个10万个元素的列表和集合
from random import sample # 从random包里import随机采样函数sample
test_list = sample(range(1_000_000), 100_000) # 从0到100万,随机采样10万个整数,获得一个列表l
s = set(l) # 根据列表l,生成集合s
init_time=time.time()
new_list=[i for i in s if i>=2]
print("{:.20f}".format(time.time()-init_time))
init_time2=time.time()
a=[]
for i in s:
if(i>=2):
a.append(i)
print("{:.20f}".format(time.time()-init_time2))
0.00897049903869628906
0.01758313179016113281
3. 三种决策结构
大部分编程语言基本都有三决策种结构:顺序结构、条件结构、循环结构
3.1 顺序结构
顺序结构最为常见,即程序从上往下执行,比如:
a = 1
print(a)
1
上面所讲的大部分代码流程,都体现着顺序结构。
3.2 条件结构
条件结构,根据条件结果(True
or False
)来决定执行哪个代码块,逻辑如下:
if 条件1:
语句1
elif 条件2:
语句2
else:
语句3
a = 2
if a > 5:
print('a > 5')
elif a < 0:
print('a < 0')
else:
print('0 <= a <= 5')
0 <= a <= 5
这个也比较简单,这里不赘述
3.3 循环结构
Python里面有两种循环结构,for
循环 和 while
循环,结构分别如下:
for 变量 in 序列:
语句1
while 条件:
语句
# 定义列表
l = [21, 45, 12, 45]
# 使用for循环,遍历元素
for element in l:
print(element)
21
45
12
45
# 使用for循环,使用下标,遍历元素
for idx in range(len(l)):
print(l[idx]) # 根据下标,打印元素
21
45
12
45
# 使用while循环,迭代列表元素
idx = 0
while idx < len(l): # 当下标小于列表长度时,执行循环内部语句
print(l[idx]) # 根据下标,打印元素
idx += 1 # 下标+1
21
45
12
45
可以在循环内部,
- 使用
break
跳出循环 - 使用
continue
结束当前循环,继续下一轮循环
# 使用break跳出循环
for element in l:
print(element)
if element == 45: # 当遇到元素为45时,跳出循环
break
21
45
# 使用continue跳过当前循环
for element in l:
if element == 45: # 当元素为45时,结束当前循环,进入下一轮循环
continue
print(element)
21
12
这里注意,Python里面没有do while
语句,如果大家学过C或者Java等语言应该会比较了解,这里不展开了。
这里介绍几个实践经验:
- 为了减少运算,请及时跳出循环,尤其是我们在处理大数据量下;(尽量减少循环次数,提升代码效率)
continue
可以减少代码嵌套层数,使代码更加优雅;
# 上面代码一个等价的写法
for element in l:
if element != 45:
print(element) # 嵌套层级较多,比较难看
21
12