学习Python全套代码【超详细】Python入门、核心语法、数据结构、Python进阶

空值None是Python中的一个特殊值,它代表空值,表示“什么都没有”,None同时也是关键字。None的用处有很多,比如说你想定义一个变量,但一时还没想好给它赋什么值,甚至连它用什么类型也没决 定好,这时可以先用None。

temp = None
print(temp)


None被输出的时候显示为一个字符串"None"

2.2.5 类型转换
2.2.5.1 布尔值转换

要想把其他值转换为布尔值,需要使用一个内置函数bool(),我们在控制台按顺序输入以下的代码:

Python


# 以下值都为True
bool(1)
bool(-1)
bool(255)
bool(0.0000001)
bool(-99.99)

# 下面的值为False
bool(0)
bool(0.0)


通过上面的代码,不难总结出:对于数值类型,所有的非零值转换为True, 只有零值才转换为False. 字符串也可以转换为布尔值

# 这是一个空字符串,转换结果为False
bool("")

# 转换结果为True
bool("abc")

# 这是一个只包含一个空格的字符串,转换结果为为True
bool(" ")


对于任何非空的字符串,转换为布尔值都是True。注意第一行代码和第三行代码。

空值转换为布尔值永远都是False(敲黑板)

# 结果为False
bool(None)


2.2.5.2 字符串转换

首先介绍一下我们可以使用str() 将其他类型转换为字符串,

True, False, None 这三个值转换为字符串就是它们的单词本身,实际上在实际编程中,我们很少需要把它们转换成字符串来使用。

str(True)
str(False)
str(None)
# 结果是'True' # 结果是'False' # 结果是'None'


对于数值类型,我们也可以用str()将它们转换为字符串,

print("My age is", str(18))


在上面的例子中,我们使用str()将18转换为"18",然后再输出。实际上,在这个例子中,如果不进行强制转换的话,也不会出错,那是因为,print函数会自动将数值先转换成字符串再输出。

2.2.5.3 数值转换

数值转换是我们在数据分析过程中经常用到的,因为我们从任何文件中读到的数字一开始都是字符串, 需要将它们转换为数值才能进行运算。

如果想要把一个整数字符串转换为int类型,使用int();

num = "1"
int(num) + 1


如果将int()去掉,这段代码则会报错,因为num是个字符串,不能将字符串和数值进行相加。

数值的前后带有空格也可以成功转换:

int(" 100 ")
# 结果为100


带有符号的数字也可以成功转换

int("-1")  # 结果为-1 
int("+1")  # 结果为1



如果想要把一个带小数点的字符串转换为float类型,使用float() pi = “3.1415926”

float(pi)


int类型和float类型之间也可以相互转换

int(3.14)  #结果为3
int(9.9)  # 结果为9
float(100)  # 结果为100.0


注意第二行中,9.9并没有转换为10,虽然这样更符合我们的常识,四舍五入嘛,但float在被转换为int的过程中,它的小数部分精度将被丢弃,只取整数部分。所以在将float转换为int的过程中,永远要小 心。

那如果想要四舍五入的来转换呢,毕竟这样更符合我们的需求。Python给我们提供了一个内置函数: round

round(9.9)  #结果为10 
round(9.5)  #结果为10
round(9.49) #结果为9


甚至,round函数让我们可以指定要保留小数点后几位:
保留小数点后两位,由于第三位是1,所以结果是3.14 round(3.1415926, 2)
保留小数点后三位,由于第四位是5,所以结果是3.142 round(3.1415926, 3)

布尔值也可以转换为int或者float

int(True)  # 结果是1
int(False)  # 结果是0

float(True) # 结果是1.0
float(False)# 结果是0.0


观察一下,恰好是数值类型转换为布尔类型的相反过程。

第三节 运算符
2.3.1 算术运算符

Python中进行数值运算需要的符号如下,我们来一一学习一下。

运算符	描述	    实例
+	    加	    1 + 1; a + b
-	    减	    10 - 5; a - b -c
*	    乘	    4 * 2 相当 4 × 2
/	    除	    4 / 2 相当于 4 ÷ 2
//	    取整除	10 // 4 结果是 2
%    	取模		10 % 4 相当于 10 - (10 // 4) × 4
**	    指数		2 ** 3 相当于 2 * 2 * 2,也就是2的3次方
()	    小括号	提高运算优先级,比如: (2 + 8) * 3


我们来看几个例子:

print(1 + 1) 
print(10 - 5) 
print(4 * 2) 
print(4 / 2)  # 结果是2.0


上面的例子都是简单的加减乘除,我们用肉眼就能观察出结果,需要注意的是除法运算, 当我们使用单斜杠除法运算符时,即使除数和被除数都是整数,它的返回结果也是一个浮点数。

print(5 / 2)  # 结果是2.5 
print(5 // 2)  # 结果是2


当我们需要对两个整数进行除法运算,且对结果的小数精度要求不高的时候,一般使用双斜杠来进行运算,这样能保证结果也是整数,不用再进行类型转换。

print(10 / 3)  # 结果是3.3333333333333335


上面这行代码的结果很有意思,我们都清楚,10 ÷ 3的结果是3.333…无限循环小数,但无限循环小数毕竟是个数学概念,计算机无法表达,所以只能显示到一定的位数。细心的你可能会发现最后一位为什么是5呢?四舍五入的话也应该是3呀。这是因为小数以二进制形式表示时的有穷性导致的,也就是计算机底层机制的原因。这里面的细节大家可以先不管,但要记住进行浮点数运算时是有精度问题的。

print(10 % 4)  # 结果是2
print((2 + 8) * 3)  # 结果是30


取模运算符大家先暂时可以理解为取余数,记住以下几个规则:

  1. 当两个数能整除时,取模运算的结果为0,比如 8 % 4 的结果是0
  2. 当0<a<b时,a % b = a,比如 3 % 8 的结果是3
  3. 当两个数中有负数时,结果可能会跟我们预料的不同,记住这个公式就行了 :a % b 就相当于a - (a // b) * b
2.3.2 使用算术运算符操作字符串

对,没有看错,字符串在Python中也可以“运算”,有两种操作,我们先看看加法。

print("Hello " + "world")


加号可以将两个字符串拼接成一个字符串,也可以将多个字符串拼接在一起:

print("apple " + "apple " + "apple ")


那如果有太多的"apple"怎么办呢?总不能一直加下去吧,这时候我们可以使用"*"运算符,表示将该字符串重复几次并拼接成一个字符串。

print("apple " * 5)


使用加号拼接字符串时需要注意,不能将字符串与数值一起相加,比如说我们要给用户发现一条查询积分的消息:

print("您账户积分为:" + 500)


这样写将会报错,所以我们要在拼接之前,先将500转换为字符串,运用我们上面学过的知识,修改成这样:

print("您账户积分为:" + str(500))


2.3.3 赋值运算符

赋值操作其实我们已经用过了,在前面定义变量的时候我们都会使用等于号。

num = 1
name = "Smith"


结合上面的运算符,我们可以做更多的赋值操作:

运算符	描述				实例
+=		加法赋值运算符	c += a  等效于 c = c + a
-=		减法赋值运算符	c -= a  等效于 c = c - a
*= 		乘法赋值运算符	c *= a  等效于 c = c * a
/=		除法赋值运算符	c /= a  等效于 c = c / a
//=		取整除赋值运算符	c //= a 等效于 c = c // a
%=		取模赋值运算符	c %= a  等效于 c = c % a
**=		幂赋值运算符		c = a   等效于 c = c a


我们在日常编程中最常用的是加法赋值和减法赋值,比如设置一个计数器,每次+1

count = 0
count += 1
count += 1


执行了两次加法赋值操作后,count的值变成了2。

2.3.4 比较运算符

比较运算符是用来运算布尔值的, 将两个值放在一起比较,最后得到True或者False。

运算符	描述		实例
==		等于		100 == 100
!=		不等于	100 != 99
>		大于		2 > 1
<		小于		1 < 2
>=		大于等于	3 >= 2
<=		小于等于	2 <= 3


我们可以在控制台cmd中的python里输入一些比较运算,看看它们的返回值是什么

100 == 100  # True
100 == "abc"  # False
1 != 2  # True
2 != 2  # False
3 > 3  # False
3 >= 3  # True
2 < 3  # True
2 <= 3  # True


这都是符合我们的常识的操作,大家在控制台里试着敲一遍就明白了。下面再试试一些比较特殊的例子:

100 == "100"   # False
100 == 50 * 2  # True
str(100) == "100"  # True
1.0 != 1  # False
int(1.9) == 1  # True


需要注意的一点是,数值100 和字符串"100"是不相等的,这一点尤其要小心,这种隐藏的bug很难被发现。

2.3.4 逻辑运算符

真实的程序中,常常需要判断的条件是复杂的,所以我们需要逻辑运算符将多个比较运算连接起来。

运算符	逻辑表达式	描述	 
and		x and y		任意一个是False,结果就是False	True and False 结果为False
or		x or y		任意一个是True,结果就是True;	True or False 结果为True
not		not x		将条件取反	not False 结果为True


我们来看几个例子:

# 定义两个变量 
a, b = 1, 2 

a > 0 and a < b  # True

a % 2 == 0 or b % 2 == 0  # True

not a > b  # True


and, or, not它们也是Python中的关键字,这是经常需要使用的三个关键字。掌握好逻辑运算符是学好任何一门编程语言的基础。

逻辑运算符可以与赋值操作组合,让你的代码更老练:

a = 0 or 100   # a=100
b = 1 or 2  # b=1


第四节 流程控制

经过前面三个小节的学习,我们已经对Python编程语言有了一个初步的了解。如果说Python是一条蟒蛇,变量、数据类型、运算符就是它的肌肉和骨架,而流程控制相当于它的神经系统,掌握了流程控 制知识,就可以让Python灵活的游动起来。

Python的流程控制比较简洁,主要分为两块:条件判断和循环控制。

2.4.1 条件判断
2.4.1.1 if…else…语句

在这里要介绍两个重要的关键字,if 和 else,看它们的字面意思就能猜到它们表示“如果”… “否则”… 我们来看看在代码中如何使用

num = 3

# 通过取模运算判断num是否能被2整除
if num % 2 == 0:
   print(str(num) + "是一个偶数")
else:
   print(str(num) + "是一个奇数")


这一波段代码是一个完整的逻辑,今后我们写的程序会更复杂,但也只不过是这段代码的重复和组合而 已。

2.4.1.2 elif

上面的例子中是一个非常简单的逻辑,一个整数,它要么是偶数要么是奇数,如果说再复杂一点的条件,我们该如何写呢?比如说来判断一个学生的考试成绩,60分以下的为不及格,60~90分为合格,90 分以上为优秀,这里面有三个条件。

score = 59

if score < 60:
   print("您的考试成绩不及格")
elif score < 90:
   print("您的考试成绩合格")
else:
   print("您的考试成绩优秀")


在这个例子中,使用了一个新的关键字"elif", 它只能用在if判断之后,else之前。

2.4.1.3 if 条件嵌套

还是以学生考试成绩的例子来说,现在我们想对60-100分的进行更细的划分,60-70分为合格,70-90 分为良好,90分以上为优秀。

score = 100

if score >= 60:
	if score < 70:
       print("您的考试成绩为合格")
   elif score < 90:
       print("您的考试成绩为良好")
   else:
       print("您的考试成绩为优秀")
else:
   print("您的考试成绩不及格")


嵌套循环可以嵌套无数层,但通常我们都建议尽量减少嵌套的层数,以增加代码的可读性。

2.4.1.3 与逻辑运算符组合
age = 22
if age > 18 and age < 60:
   print("你已经不是个孩子啦,该去工作啦")


上面的例子表示,年龄大于18岁并且小于60岁,也可以这样写:

age = 22

if 18 < age < 60:
   print("你已经不是个孩子啦,该去工作啦")


这样的代码更简洁,可读性更高,这是Python特有的简洁写法。

2.4.1.4 自动类型转换

if 和 elif 的后面总是跟着一个表达式,这个表达式的结果必须是True或者False,如果表达式运算出来的结果不是一个布尔值,则会自动将结果转换为布尔值,无论它是什么类型的值。转换的结果遵循我们之 前学过的布尔转换规律。

count = 0

if count:
	print("条件成立")
else:
	print("条件不成立")


试着将count的值改为1,条件则成立了。

result = None
if result:
   pass
else:
   print("什么收获都没有")


记住:0值、None 和空字符串转换为布尔值后都是False

pass是Python的关键字,它表示什么也不做。

2.4.2 循环

看到循环我们首先会想到一些物体,比如旋转的风扇、车轮,一个圆的形状。一个圆形的跑道,如果沿着它跑,除非我们自己停下来,永远不会有终点,但是可以计算我们跑了多少圈。假设我们在跑步之前,给自己设定一个目标,跑完10圈就不跑了,然后去一圈一圈的跑完了10圈,停止。这个过程就很像代码里的循环语句了。

2.4.2.1 while循环
lap = 0

while lap < 10:
   lap += 1

   print("我跑完了第" + str(lap + 1) + "圈")


运行上面的代码,会得到以下的输出:

我跑完了第1圈
我跑完了第2圈
我跑完了第3圈
我跑完了第4圈
我跑完了第5圈
我跑完了第6圈
我跑完了第7圈
我跑完了第8圈
我跑完了第9圈
我跑完了第10圈


2.4.2.2 for循环

for循环可以用来遍历序列,序列指的是一个可迭代的有序的集合,比如字符串就是一个序列,下面我 们用for循环来打印出一个字符串中的所有字符。

seq = "hello"

for s in seq:
   print(s)


这段代码的输出如下:

h
e
l
l
o


也可以用for循环来打印一连串的数字,这里需要用到一个新的内置函数:range。

for i in range(5):
   print(i)


range函数的作用就是提供一个从0到4的迭代器,而for可以遍历这个迭代器。注意是从0开始的,整个循环一共打印了5个数。

输出结果是:

0
1
2
3
4


我们可以修改一下之前写的跑圈的while循环,改用for循环加range函数来实现:

for lap in range(10):
   print("我跑完了第" + str(lap + 1) + "圈")


对比一下,哪种写法更简洁,更优雅 ?很明显是用for循环这种。这里面有一个细节需要注意,由于lap的值是从0开始到9结束,所以我们需要在输出的时候给它+1。

2.4.2.3 嵌套循环

既然掌握了两种循环写法,那可以把它们组合起来运用,我们来写一个例子,在控制台中打印出指定边长的长方形或者正方形图案。

# 指定长方形的宽和高
width, height = 10, 5

# 因为是从上往下开始打印,所以先遍历高度

for i in range(height):
	for j in range(width):
		print("*", end="")
	print()


在这里,print函数有了第二个参数,end表示在打印完指定的内容后,在结尾再打印一个指定的字符串,默认每个print语句在结尾会加一个换行符"\n", 传递一个空字符串给它,表示打印完星号以后不再添加任何输出内容。

第二个print函数没有任何参数,那它会输出一个换行符。

所以整个程序的逻辑就是每输出10个星号后,输出一个换行符,最终输出的图案如下:

**********
**********
**********
**********
**********


既然可以打印出一个长方形,那我们也可以打印一个直角三角形:

*
**
***
****
*****


代码如下

for i in range(5):
   	for j in range(i + 1):
       	print("*", end="")
   	print()


再来一个稍微复杂一点的案例,打印出这样一个九九乘法表:

1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81


代码如下:

for i in range(1, 10):
   	for j in range(1, i + 1):
       	print("%s*%s=%s" % (j, i, i * j), end=" ")
   	print()


2.4.2.4 break 和continue

有时候在循环内部,我们需要临时略过某一次循环或者干脆跳出整个循环,这时候就需要用到break和continue。

在下面这个例子中,我们使用for循环和continue来打印出10以内的所有奇数相加的式子,并求出它们的和。

total = 0

for i in range(10):
   	if i % 2 == 0:
       	continue
   	print(i, end=" + ")
   	total += i

print(" = %s" % total)


关键字break用来打断整个循环并跳出。看这个例子,给一个字符串,这个字符串是一个小数,要求打印出小数的整数部分。

s = "238.9237834829"

for i in s:
   	if i == '.':
       	print()
       	break

   	print(i, end='')


小数的整数部分都在小数点的左边,而我们遍历字符串是从左往右,所以当遇到小数点后,就停止遍历,这样就正好实现了打印这个小数的整数部分。

2.4.3 演示:智能密码锁程序

最近几年很流行的智能密码锁程序,除了可以用指纹开锁、人脸识别开锁外,都会有密码开锁的功能, 以防万一。密码开锁功能是这样的,首先设定好密码,以后每次开锁的时候只要输入的数字中含有设定的密码,就视为解锁成功。这样的设定是为了防止别人的窥探,具有更高的安全性。

首先,由于涉及到了输入,先来学习一下Python内置的输入函数: input

password = input("请设置您的密码")


在执行到这行代码时,控制台就变成光标闪烁的状态,用户可以用键盘进行字符的输入,输入完成后, 再输入一个回车表示输入结束,输入的字符串赋给等号左边的变量。

# 设置初始密码
password = "123"

while True:
	pwd = input("请输入您想要设置的密码:")
   	# 如果没有输入任何密码,则使用初始密码作为密码
   	if not pwd:
       	break
   	confirm_password = input("请再次输入您的密码:")
   	if pwd == confirm_password:
       	password = pwd
       	break
   	else:
       	print("您两次输入的密码不一致,请重新输入。")

print("您的初始密码已设置为:" + password)
print("进入开锁程序。。。")

# 开锁
while True:
   	input_pwd = input("请输入您的密码:")
   	# 判断输入的密码中是否包含密码
   	if password in input_pwd:
       	print("开锁成功!")
       	break
   	else:
       	print("您输入的密码有误,请重新输入")


注意 password in input_pwd 这行代码,关键字in表示如果在指定的序列中找到值返回 True,否则返回 False。

第三部分 数据结构

第一节 字符串

在任何一门编程语言中,字符串都是最基础、最重要的数据结构。前面我们已经学习过字符串的基本使用方法,现在继续深入的学习更多的知识。

3.1.1 字符串的格式化输出
3.1.1.1 格式化运算符

在之前while循环的一个例子中, 有这样一行代码:

print("我跑完了第" + str(lap + 1) + "圈")


这里我们使用了两个加号做了字符串拼接,并且将整形转换成了字符串,现在介绍一种更好的办法,使用格式化输出来打印这句话。

print("我跑完了第%d圈" % 1)


这里的百分号就是格式化符号,跟模运算符一样,但在不同的地方用法不一样。%d是一种占位,表示 要显示在这里是一个整数,常用的占位符有以下几种:

占位符	描述
%d		整数占位符
%f		浮点数占位符
%.f		指定精度的浮点数占位符
%s		字符串占位符
%%		输出百分号%


如果给%d 传入一个浮点数,那它会自动将它转换成整数

print("%d" % 3.14)  # 输出3
print("%d" % 3.99)  # 输出3


转换成整数的规则和类型转换的规则一 样,不会四舍五入。

%f的用法有两种,一种就是直接使用,比如

print("%f" % 3.14)


它会输出“3.140000”,后面的0是自动补齐的,如果我们只想要输出小数点后两位,可以这样写: print(“%.2f” % 3.14)

print("%.2f" % 3.1415926)


上面的两行代码输出都是"3.14",“%.2f” 这种写法指定了小数点后面的位数,即使浮点数后面的小数部分超出了2位,也只会输出两位。如果不足两位,或者是个整数,会自动补零到两位。

print("%.2f" % 3)  # 3.00
print("%.2f" % 3.1) # 3.10
print("%s" % 100) print("%s" % 3.14)  # 输出100 # 输出3.14
print("%s" % "python")  # 输出python


%s 是胜任最广泛的占位符,它可以对应任何类型的变量。
在同一个字符串可以同时使用多个占位符:

report = "%d年%s公司营收增长了百分之%.2f" % (2019, "腾讯", 20.28) 
print(report)


当我们需要在字符串输出一个百分比,就需要用到%%,比如说:

report = "%d年%s公司营收增长了%.2f%%" % (2019, "腾讯", 20.28)
print(report)


3.1.1.2 format 函数

除了%运算符外,Python还为我们提供了字符串的format函数提供丰富的格式化。比如说,在输出一个较长的数字时,根据国际惯例,每三位用逗号分隔:

print('{:,}'.format(1234567890))  # 1,234,567,890


format函数也可以像%那样来格式化多个参数:

report = "{0}年{1}公司营收增长了{2}%".format(2019, "腾讯", 20.28)
print(report)


{0}表示第一个参数,{1}{2}表示第二、第三个参数,以此类推。这样做的好处是,如果有参数在字符串出现多次,可以不用重复的传入。

‘{0}的GDP为{1:,}…虽然它的GDP只有{1:,}美元,但它的人均GDP高达18万美元’.format(“摩纳哥”, 7100000000)

假设这个GDP数据在报告中多处被引用,万一需要修订的话,我们只需要修改一处就行了。

3.1.2 字符串的下标和切片

字符串其实也是一种序列,可以理解为一串整齐的按顺序排着队的字符,组成了字符串,那每个字符在队伍中都有自己的位置,这个位置就是下标,又叫作索引。

CHINA
12345

如上表,"CHINA"这个字符串,从左往右每一个字符对应了一个下标(索引),需要特别注意的是,在计算机编程中,所有的下标都是从0开始的,当我们要访问一个字符串的第1个字符时,使用的下标应该是0。

"CHINA"[0]


使用中括号加数字的方式,表示要访问的是具体哪个位置上的字符。

"CHINA"[1]  # 第2个字符"H"
"CHINA"[4]   # 第5个字符"A"


第5个字符"A"是这个字符串的最后一个,我们也可以这样来访问:

"CHINA"[-1]  # 最后一个字符"A" 
"CHINA"[-2]  # 倒数第二个字符"N"


使用负数下标可以从右往左访问,这种写法是Python特有的,非常的快捷,对于任意长度的字符串,我们都可以使用-1来获取它的最后一个字符,注意使用负数下标是是从-1开始的,因为-0也是0,产生重复了。

切片操作也是Python的一大特色,极大简化了序列访问和操作,

"CHINA"[0:3]


上面的切片将会得到"CHI",切片操作是以冒号隔开两个下标,冒号左边的代表开始下标,右边的代表结束下标,特别需要注意的是,结尾下标表示截取到该下标前一个位置的下标。那[0:3],一共截取了3-0=3个字符,从0开始数,0、1、2,恰好是三个。

所以如果我们用[0:0]这种写法,将会得到一个空的字符串,

"CHINA"[0:0] "CHINA"[0:-1]  # 空字符串 # CHIN


那如果想得到切片出整个字符串,可以这样写

"CHINA"[0:6]  # CHINA


但一般我们都会这样写,冒号右边的省略,表示一直截取到最后一个字符。

"CHINA"[0:] # CHINA


事实上,前面的0也可以不写,冒号左边为空表示从第一个字符开始截取。

# 从0到末尾   
"CHINA"[:]  # CHINA
# 从0到第3个
"CHINA"[:3] # CHI  
# 从第3个到末尾
"CHINA"[2:] # INA


如果想要隔一个字符取一个,可以这样写 # 每隔两个字符截取一个

"CHINA"[::2]  # CIA


第二个冒号表示截取步长,这里的2表示每两个字符取一个,如果不传,默认就是每一个都取。步长也可以为负数,如果传递了一个负数,则表示是从右往左进行截取。

# 从右往左每隔两个两个字符截取一个
"CHINA"[::-2]    # AIC


所以,如果想倒序输出一个字符串,可以这样写

"CHINA"[::-1]  # ANIHC


3.1.3 字符串函数

字符串本身有很多函数,前面其实已经学习过一个format函数,我们再来介绍几个其他的常用函数: 3.1.3.1 去除空白字符函数

先来了解一下什么是空白字符,空白符包括空格、换行(\n)、制表符(\t)。

print("A\tB\tC\nD\tE\tF")


在控制台里会整齐的输出成这样:

A B C
D E F


在C后面有一个\n换行符,所以D才会显示在了第二行。而ABC、DEF之间的空白则是\t制表符造成的。 按键盘上的空格键会产生一个空格,按回车键则会产生一个换行符,按Tab键则会产生一个制表符,用户在输入数据的时候有时候经常会误输入这几个字符,所以在在处理用户输入的数据时,要先去除头尾 的空白字符。

password = "123"
input_password = " 123"
print(password == input_password)


print输出为False,由于在1前面有一个空格,导致了密码校验失败,所以必须对用户的输入先进行处理 password = “123”

input_password = " 123"
print(password == input_password.strip())


我们在input_password后面加了一个函数strip(),现在输出变成了True。strip函数的作用就是去除字符串首尾的所有空白字符。

" abc ".strip()
"\t abc \n".strip()


得到的将是字符串"abc",但是strip函数并不会去除掉字符串之间的空白字符

" a   b   c ".strip()


得到的结果是"a b c",只去掉了首尾空白字符,保留了中间的。另外还有lstrip和rstrip函数,分别去除字符串左边和右边的空白字符。

3.1.3.2 大小写操作

这个比较简单,我们直接看代码。

# 将所有字符变成大写 
"china".upper()  
# CHINA

# 将字符串的首字母变成大写 
"china".capitalize() 
# China

# 将所有字符变成小写
"CHINA".lower()
# china

# 将每个单词的首字母变成大写 
"i have a dream".title()
# I Have A Dream


3.1.3.3 字符串判断

判断字符串是否以指定的字符串开头或者结尾

函数			说明
startswith	是否以指定的字符串开头
endswith	是否以指定的字符串结尾
isdigit		是否是一串数字
islower		是否全是小写字母
isupper		是否全是大写字母


3.1.3.4 查找与替换

在前面智能密码锁的案例中,我们用过in来判断一个字符串是否被包含在另一个字符中 password = ‘123’

input_pwd = '456123789' 

print(password in input_pwd)  # True


这样可以判断出是input_pwd中是否有password,但如果想要知道password在input_pwd中的确切位置,就需要使用find函数

input_pwd.find(password)  # 结果是3


结果是3。在input_pwd中寻找password,找到了,且它的出现的位置是3,也就是第4个字符。如果没有找到则会返回-1

input_pwd.find("notexists")   # 结果是-1


除了find函数,index函数也有相同的功能,唯一的区别是 ,index函数如果没有找到相应的字符串就会报错

input_pwd.index(password)  # 结果是3
# 这行代码将会在运行时报错 input_pwd.index("notexists")


count函数能够查找出指定的字符串一共出现了几次,如果没有出现,则返回0。

"abba".count('a')  # 2
 'abba'.count('c')   # 0


replace函数提供了替换字符串中某些部分的功能

"abba".replace('a', 'b')  # 结果是'bbbb'


'apple banana'.replace('apple', 'orange')  # 结果是'orange banana'


3.1.3.5 字符串长度

字符串本身没有测量长度的函数,需要借助一个Python内置函数len。

len("China")  # 5
len("")  # 0
len("a")  # 1


len函数非常重要,它不光可以测量字符串的长度,也可以测量其他所有有长度的对象。 r = range(10)

len(r)  # 10


3.1.4 综合案例:异常号码数据分析

结合以上的字符操作知识,可以开发一个电话号码识别程序,用户输入一串数字,程序识别它是不是一 个有效的电话号码,如果是有效电话号码,我们再识别它是一个固定电话号码、手机号码、还是400号 码。用户输入"exit"后,程序退出。

这是一个稍微复杂的需求,在动手写代码之前,我们先分析一下需求。先列举一下常见的几种电话号码 形式,手机号码是11位的,以1开头,不同运营商的前三位不一样,由于三位太多了,我们就以前两位来判断,包括13,15,17,18,19

再看固定号码,区号+电话号码的方式,区号可能是三位(010),也可能是四位(0888),电话号码是8位,那加起来一共是11位或12位。

最是400电话,这个特征很明显,以400开头,共10位。

实现代码如下:

cellphone_number_start = "13,15,17,18,19"
telephone_number_start = "010,021,022,025,0888,0555"

while True:
	num = input("请输入一个电话号码: \n")
	if num == 'exit':
		break
	if not num:
       	print("电话号码不能为空")
   	num = num.strip()
   	if not num.isdigit():
       	print("您输入的是一个无效电话号码")
       	continue

   	if num.startswith('1') and len(num) == 11 and num[0:2] in cellphone_number_start:
       	print("这是一个手机号码")
       	continue
   	elif num.startswith('400') and len(num) == 10:
       	print("这是一个广告电话")
       	continue
   	elif num.startswith("0"):   # 当代码太长时,可以用反斜杠分割成多行。
       	if (len(num) == 12 and num[0:4] in telephone_number_start) or \
(len(num) == 11 and num[0:3] in telephone_number_start):
           	print("这是一个固定电话")
           	continue
           
   	print("无法识别该号码")


第二节 元组 tuple
3.2.1 定义元组

现在我们知道了字符串是一种序列,它可以迭代循环,也可以按索引访问,也可以切片访问。但它的成员只能是单个的字符,现在来介绍一种更多元化的序列:元组,英文叫tuple,可这样来定义一个元组:

t = ('My', 'age', 'is', 18)


在这个元组中包含了3个字符串,一个整形数字,元组中的每一项称作元素,4个元素按照从左到右的顺序排列。可以用下标索引访问:

t[0]  # 'my'
t[-1]  # 18


也可以通过切片来访问,注意切片返回的是一个包含切片片段的新元组。

t[0:2]  # ('My', 'age')


事实上元组定义的时候也可以不用括号

t = 'My', 'age', 'is', 18


但当,元组中只有一个元素的时候,必须要加一个逗号:

t = ('solo',)

# 或者不带括号
t = 'solo',


可以将一个序列强制转换为元组

tuple('abc')  # ('a', 'b', 'c')

tuple(range(5)) # (0, 1, 2, 3, 4)


后面的逗号表明这是一个元组,否则就会被认为是一个字符串。

3.2.2 元组操作

现在我们介绍字符串的另一个函数join,有了它,可以把元组这样的序列拼接成一个整体的字符串。

# 注意最后一个元素
t = ('My', 'age', 'is', "18")
print(" ".join(t))  # 输出结果:'My age is 18'


注意最后一个元素,这次我们将它设置成了字符串,因为join函数要求参数序列中的每一个元素都必须是字符串。

和字符串一样,元组也有count, index函数,使用的方法也是一样:

t = ('a', 'b', 'b', 'a')

t.count('a')   # 2
t.index('b')   # 1
t.index('c')   # Error

# 查看长度 
len(t)  # 4


元组也支持 in 操作,想要判断元组中是否包含某个元素:

'a' in t  # True

'x' in t  # False


最后,需要记住的是元组和字符串都是只读的,也就是不可修改的。我们不能单独改变元组中的某个元素,或者是字符串中的某个字符。

3.2.3 遍历元组

元组属于序列,所以可以像字符串那样去遍历它:

lst = ('a', 'b', 'c', 'd', 'e')

for i in lst:
	print(i)


使用for循环可以方便快捷的遍历元组,上面的例子将打印出元组中的每一个元素。也可以使用while来遍历元组,虽然并不经常这样使用。

lst = list(range(10))
i = 0

while i < 10:
	print(lst[i])
 	i += 1


3.2.4 综合案例:销售数据统计-销冠

在真实的项目中,数据结构通常是比较复杂,经常碰到嵌套的元组,甚至是多层嵌套,我们来看一个例 子:

# 当元组元素较多、较长时,可以这样书写 
sales = (("Peter", (78, 70, 65)), ("John", (88, 80, 85)), ("Tony", (90, 99, 95)), ("Henry", (80, 70, 55)), ("Mike", (95, 90, 95)))


这是包含某公司所有销售人员第一季度销售业绩的元组,单位是万元,其中的每一个元素对应一个销售人员的信息,人员信息也是一个元组,包括姓名和业绩,业绩又是一个元组,按照顺序分别是1、2、3 月份的销售额。需求:找出总销售额最高的那个员工,并将TA的名字和总销售额输出。

champion = ''
max_amount = 0

for sale in sales:
   name = sale[0]
   quarter_amount = sale[1]
   total_amount = 0
   for month_amount in quarter_amount:
       total_amount += month_amount
       
   if total_amount > max_amount:
       max_amount = total_amount
       champion = name

print("第一季度的销冠是%s, TA的总销售额是%d万元" % (champion, max_amount))


上面的代码也可进一步优化一下,使得代码行数更少,结构更简单。

champion = ''
max_amount = 0

for name, quarter_amount in sales:
   total_amount = sum(quarter_amount)

   if total_amount > max_amount:
       champion, max_amount = name, total_amount

print("第一季度的销冠是%s, TA的总销售额是%d万元" % (champion, max_amount))


这里用到了一个sum函数,它是Python内置函数,可以计算出一个序列里所有数值的总和。

第三节 列表 list
3.3.1 定义列表

列表可以理解为可变的元组,它的使用方式跟元组差不多,区别就是列表可以动态的增加、修改、删除元素。

看一下列表的定义:

# 定义一个空列表
lst = []
lst = list()

# 定义带有初始值的列表
lst = [1, 2, 3]
lst = ["a", 1, 2, 3, "b", "c"]
lst = list(range(5))
lst = list("abc")
lst = list((1, 2, 3))


以上方式都可以定义一个列表。注意变量名使用了lst,有意的避开了list,虽然list不是关键字,但我们在命名变量的时候不要使用这些内置名称,否则可能会引起无法预知的错误。

3.3.2 增删改查

列表的访问和字符串、元组一样,索引或者下标都可以。

lst = ['a', 'b', 'c', 'd', 'e']
lst[0]  # 'a'
lst[1:3]  # ['b', 'c']


列表是可以修改的, 还是以上面的lst为例:

lst.append('x')


往lst里添加了一个元素,现在列表变成了

['a', 'b', 'c', 'd', 'e', 'x']


注意append函数总是在列表后面添加元素,列表的长度也增加了1.因此原来list[-1]的值从原来的’e’变成 了’x’,

len(lst)   # 6
lst[-1]  # 'x'


修改列表中的元素

lst[-1] = 'f'

# 修改后列表变为:
# ['a', 'b', 'c', 'd', 'e', 'f']


删除列表中的元素

del lst[0]
# 删除后列表变为:
# ['b', 'c', 'd', 'e', 'f']


注意,由于我们删除的是第一个元素,现在剩下的所有元素的索引都发生了变化,第一个lst[0]变成了’b’,后面的也都往前挪了一位。但是lst[-1]没有变,还是’f’。涉及到删除操作的时候要小心,防止使 用错误的索引。

3.3.3 列表函数

列表也是一种序列,它也具有index和count函数和支持len函数,这些函数的用法和元组一样,它的循环遍历也和元组一样,不再赘述。下面来介绍一下列表特有的一些函数。

insert

insert函数和刚刚介绍的append函数一样,用来向列表中添加一个新的元素,区别就是append是在最后添加,insert则可以向任意位置添加。

lst = ['a', 'c', 'e']

# 在第二个元素'c'前面插入一个字符串'b'
lst.insert(1, 'b')

# lst现在的值是['a', 'b', 'c', 'e']

# 在最后一个元素'e'前面插入一个字符串'd'
lst.insert(-1, 'd')

# lst现在的值是['a', 'b', 'c', 'd', 'e']


pop

每次调用pop函数会从列表中“弹”出一个元素,接着上面的lst操作

temp = lst.pop()

print(lst)  # ['a', 'b', 'c', 'd']
print(temp)  # 'e'


我们发现列表最后一个元素’e’不见了,并被在控制台打印出了。如果想“弹”出其他位置的元素,可以传 一个位置参数给pop函数,像这样:

temp = lst.pop(2)

print(lst)  # ['a', 'b', 'd']
print(temp)  # 'c'


remove

前面我们已经学习了使用del关键字去删除列表元素,del操作可删除指定下标索引的元素,如果我们要删除指定内容的元素,就需要用到remove函数。

lst = [1, 2, 1, 'a', 'b', 'c']

lst.remove('a')
print(lst)  # lst的值为[1, 2, 1, 'b', 'c']

lst.remove(1)  # 注意这里的1是元素值,不是索引
print(lst)  # lst的值为[2, 1, 'b', 'c']


remove函数会从左至右找到与指定的值相匹配的第一个元素,并将它删除。在使用的时候需要区分del, pop, remove的区别。

clear

clear函数会清空列表内的所有元素。

lst = [1,2,3,4]

lst.clear()
print(lst)  # 结果为[]


extend

extend函数有点像append函数,但append函数每次只能添加一个元素,而extend可以添加一组。 lst = []

lst.extend(range(5))
print(lst)  # [0, 1, 2, 3, 4]

lst.extend([5, 6, 7])  
print(lst)  # [0, 1, 2, 3, 4, 5, 6, 7]


reverse

将整个列表反转,以上一步的lst为例

lst.reverse()
print(lst)  # [7, 6, 5, 4, 3, 2, 1, 0]


sort

按照一定的规则将列表中的元素重新排序,对于数值,默认按从小到大的顺序排列。 lst = [3, 5, 2, 1, 4]

lst.sort()

print(lst)  # [1, 2, 3, 4, 5]


如果想要让列表从大到小排列,可以加上reverse参数。 lst = [3, 5, 2, 1, 4]

lst = [3, 5, 2, 1, 4]
lst.sort(reverse=True)

print(lst)  # [5, 4, 3, 2, 1]


对于字符串,则会按照它们的ASCII值的顺序排列。ASCII是基于拉丁字母的一套电脑编码系统,所有的编程语言都支持ASCII编码。ASCII值一共有128个字符,包含数字0~9,字母a-z, A-Z,还有一些常用的符号。每一个字符对应一个数字,比如字母’A’对应的就是65, 字母’B’对应66,等等。在Python中,可以使用内置函数将字符与它的ASSCII值互转。

ord('A')  # 65

chr(66)  # 'B'


sort函数会比对每个字符串的第一个字符,如果第一个字符相同,则比对第二个字符,以此类推。

fruits = ['apple', 'banana', 'orange', 'blueberry']

fruits.sort()
print(fruits)  # ['apple', 'banana', 'blueberry', 'orange']


注意观察"banana"和"blueberry"的顺序。

如果列表的元素不是简单的字符或者数字,那怎么进行排序呢,比如有下面一个列表,它存储了公司第一季度每个月的收入。

revenue = [('1月', 5610000), ('2月', 4850000), ('3月', 6220000)]


注意列表中的每一个元素是一个元组,元组的第一项是月份,第二项是销售额,现在想要按照它的销售额来从高到低排序。如果直接调用sort函数,它会按照元组中第一项的字符串顺序进行排序。

revenue.sort(reverse=True)  # 排序后为 [('3月', 6220000), ('2月', 4850000), ('1月', 5610000)]


这显然不对,2月的收入比1月低,应该排到最后。这时应该传递key参数

revenue.sort(reverse=True, key=lambda x:x[1])  # 排序后为 [('3月', 6220000), ('1月', 5610000), ('2月', 4850000)]


key参数接收的是一个函数,我们在这里给它传递了一个匿名函数,关于函数的使用后面再学习,这里我们需要了解是通过key参数,我们指定了sort排序的依据,就是每个元组里面的第二项。

copy
lst1 = [1, 2, 3]
lst2 = lst1
lst1.append(4)


上面的代码执行完成以后,lst 和 lst2的值都变成了 [1, 2, 3, 4] ,但我们在代码里面只修改了lst1, lst2的值也跟着改变了,这不符合我的预期,可能会导致bug。所以,如果我们想要创建一个跟lst1一模一样的新列表,且不再受它以后操作的影响,就可以使用copy函数:

lst1 = [1, 2, 3]
lst2 = lst1.copy()

lst1.append(4)

print(lst1)  # [1, 2, 3, 4]
print(lst2)  # [1, 2, 3]


3.3.4 列表表达式

列表表达式是一种快捷的创建列表的表达式,可以将多行代码省略为一行。比如,列出20以内的所有偶数

[i * 2 for i in range(10)]  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]


当然,上面的代码我们也可以这样实现

[i for i in range(0, 20, 2)]


range函数可以接收三个参数:第一个是起始数值(包含),可以省略,默认从0开始;第二个是结束数值(不包含);第三个是步长,可以省略,默认为1。是不是有点像切片操作?

上面的代码就相当于:

even_nums = []

for i in range(0, 20, 2):
	even_nums.append(i)


对比来看,列表表达式确实更简洁更优雅,再看一个例子,打印出大写的26个字母。

# 65是大写字母‘A’的ASCII值
print([chr(i) for i in range(65, 65 + 26)])


3.3.5 综合案例-销售数据统计-排行榜

再进一步,还记得前面写过的找出销售冠军的例子吗?

sales = (("Peter", (78, 70, 65)), ("John", (88, 80, 85)), ("Tony", (90, 99, 95)), ("Henry", (80, 70, 55)), ("Mike", (95, 90, 95)))


现在我们将计算出每人的总销售额,并按销售额从多到少,存放到一个列表里。

top_sales = []

for name, quarter_amount in sales:
   total_amount = sum(quarter_amount)
   top_sales.append((name, total_amount))

top_sales.sort(key=lambda x:x[1], reverse=True)
print(top_sales)


得到了一个下面的列表

[('Peter', 213), ('John', 253), ('Tony', 284), ('Henry', 205), ('Mike', 280)]


提示:这个案例用列表表达式来开发,将会非常快速。

top_sales = [(sale, sum(amount))for sale, amount in sales]
top_sales.sort(key=lambda x:x[1], reverse=True)

print(top_sales)


列表表达式是一种非常强大和方便的写法,不要求大家掌握,如果不会写列表表达式,也可以用for循环或while循环的方式来写,但至少要能看懂。

第四节 字典 dict

类似这种销售信息的数据结构,我们使用元组或者列表存储是可以的。

top_sales = [('Peter', 213), ('John', 253), ('Tony', 284), ('Henry', 205), ('Mike', 280)]


可以很方便的取出在这个榜单中第一名、第二名或者任意一名的销售数据。但它有一个缺点,如果我们想取出特定的某个销售人员的数据时,它会很麻烦。比如如果想要找出Mike的数据,只能去循环遍历,一个个的去比对。

for sale, amount in top_sales:
   if sale == 'Mike':
       print(sale, amount)


这样不光写起来麻烦,执行效率也很低,假设这是一个庞大的销售数据库,那要花多少时间寻找呢?所以必须使用字典。

3.4.1 字典的定义

使用花括号,可以直接定义字典

sales = {
 'Peter': 213,
 'John': 253,
 'Tony': 284,
 'Henry': 205,
 'Mike': 280
}


每一行冒号左边的是键(key),右边的是值(value),称作键值对,以逗号分隔开。在这里我们故意写成每行一个键值对,实际并不要求每行一个,只要用逗号分隔开来就可以。键是不能重复的,值可以重复。

对于top_sales 这种两个一组、一一对应的列表来说,可以直接转换为字典。

sales = dict(top_sales)  # sales现在的值变成了


{
 'Peter': 213,
 'John': 253,
 'Tony': 284,
 'Henry': 205,
 'Mike': 280
}


3.4.2 增删改查

有了字典,那现在就可以快速的取出任意一个人的数据了

sales['Mike']

sales['Henry']


注意,键的名称是区分大小写的,‘Mike’ 和 'mike’分别对应了不同的键。

sales['mike']  # KeyError: 'mike'


这行代码将会报错,因为不存在’mike’这个键。在访问之前,需要先往字典中添加数据相应的键:

# 值可以先设置为None或者0
sales['mike'] = 0


修改字典中的数据:

sales['mike'] = 300


删除字典中的数据

del sales['mike']


3.4.3 遍历字典

字典的遍历和列表、元组、字符串有所区别,由于它的每一项都是一个键值对,所以在遍历时也要注意。

for key_value in sales.items():
   	print(key_value)


注意 sales.items() 这种写法,在遍历字典时,这是一种通用的写法。items函数将字典内的内容转换成了一种可迭代的序列,以供for循环遍历,遍历出来的每一项是一个元组,包含了键和值。所以通常 我们直接写成这样:

for key, value in sales.items():
   	print(key, value)


注意中间的逗号和最后的打印结果。

如果不使用items函数,那遍历的就是字典所有的key。

for key in sales:
   	print(key)


3.4.4 字典函数

字典有一些函数和列表是一样的,比如clear, copy,这两个不再介绍,我们来看看其他的函数。

get

如果直接访问字典中一个不存在的key,就会产生报错,所以,通常我们如果不确定是否存在某个key 时,会先判断一下:

if 'mike' in sales:
	print(sales['mike'])

else:
 	print('mike', 0)


in关键字又一次派上用场了, 在这里用in来检查字典中是否包含"mike"这个键,如果包含则返回True, 无论"mike"所对应的值是否为空。这样的写法,很麻烦,每次都要先判断,再查询,这时候get函数就派上用场了。

sales.get('mike', 0)


这一行短短的代码就实现了上面4行代码的功能,它表示在字典中查询’mike’键所对应的值,如果不存在’mike’键,则返回0。这里的0可以替换成任何其他的默认值,这样就极大简化代码逻辑。

keys/values

如果只想单独列出所有的销售人员名单,可以这样写:

sales.keys()


可以对它进行遍历

for sale in sales.keys():
 print(sale)


如果只想计算出所有销售人员的销售额总和,也就是公司总销售额,可以直接取出value部分并求和: sum(sales.values())

第五节 集合 set

集合在Python中是一个无序的不重复的序列,一般用来删除重复数据,还可以计算交集、并集等。

3.5.1 集合的定义

这两方式都可以定义一个集合

nums = {1, 2, 3, 4, 5}

nums = set([1, 2, 3, 4, 5])


注意,集合是无序的,虽然我们在书写的时候是按照从小到大的顺序,有时候遍历出来也是有序的,但不能把它视为有序,并作为某些逻辑的依据。

集合最常用的用法是用来消除列表或者元组中的重复元素

lst = [1, 2, 1, 3, 4, 5]

list(set(lst))


列表里里面有两个1,先将lst转成了集合,再将集合转成了列表,最终得到了一个没有重复元素的列表 [1, 2, 3, 4, 5] ,注意最后得到的列表的顺序有可能跟原来是不一样的。

3.5.2 遍历集合

集合的遍历和列表、元组很相像,再次重申,它不是有序的。

for n in nums:
 	print(n)


也可以通过len函数来测量它的长度,准备地讲,在数学上叫集合的基数。

len(nums)  # 5


可以通过 in 来判断集合中是否有某个特定的元素

5 in nums  # True


3.5.3 增删改查

往集合里添加一个元素

nums.add(5) # do nothing

nums.add(6)


如果集合里已经有这个元素了,则什么也不做。像上面的第一行代码,什么也没有做。 已经加入集合的元素不能修改,只能删除,删除集合里的元素:

nums.remove(5)
nums.remove(5)  # Error


remove函数会从集合里删除指定元素,但如果元素不存在,则会报错,上面的第二行代码就会报错。 如果不想报错,可以使用diiscard函数。

nums.discard(5)


从集合内删除并返回一个元素:

num = nums.pop()


如果集合是空的,则会报错。有时候,我们也会使用pop函数来迭代一个集合。

while len(nums) > 0:
	print(nums.pop())


这样的好处是可以保证每个元素只被使用一次,不会重复使用。

3.5.4 集合函数
# 定义两个集合
s1 = {1, 2, 3}
s2 = {3, 4, 5}

# 求交集
s1.intersection(s2)  # {3}

# 求并集
s3 = s1.union(s2)   # {1, 2, 3, 4, 5}
print(s3)

# 是否是子集
s1.issubset(s3)   # True

# 是否是父集
s3.issuperset(s2)  # True


第四部分 Python进阶

第一节 函数

在前面的学习过程中,我们已经接触了很多次函数,现在我们来好好的认识一下这个重要的小伙伴。函数就是一段可以重复调用的代码,在Python中函数是非常重要的概念,在编程中几乎无处不在。

4.1.1 函数定义及调用

在Python在, 我们使用def关键字来定义函数

def hello(name):
	print("Hello", name)


上面的代码定义了一个最简单的函数,它的作用就是打印出"Hello"加一个名字。我们看看它的结构:

调用hello函数,将会打印“Hello, Python”

hello("Python")


在这个过程中发生什么什么事呢?这实际上是将name传递给hello函数,也就是将name的值设置为"Python",并执行函数体内的代码。

4.1.2 函数的参数

函数的参数可以有一个,也可以有多个,也可以没有参数。这取决于在定义函数的时候如何定义参数部分。刚才我们定义的函数只有一个参数,现在我们定义两个参数的函数。

def hello(name, sex):
	if sex == '男':
		print("Hello, Mr", name)

   	elif sex == '女':
   		print("Hello, Miss", name)


这个函数有两个参数,name和sex,分别表示用户的名字和性别,以便显示不同的尊称。我们在调用的时候,要注意参数的顺序,不能前后颠倒。调用函数:

hello("Zhang", "男")

hello("Wang", "女")


如果参数较多,记不清它们的顺序,可以写上参数名,这样就不用管顺序了。

hello(sex='男', name='Zhang')


如果说用户大多数是女的,只有少部分的男性,那这个函数还可以改造一下,我们让它的sex参数默认就是“女”:

def hello(name, sex='女'):
	if sex == '男':
		print("Hello, Mr", name)
	elif sex == '女':
		print("Hello, Miss", name)


和上面的函数相比,只是在sex参数后面加上一个默认值,这样,后面用户没有填性别信息的时候,就会默认为女性。

hello("Wang")


如果每一个参数都有默认值,在调用的时候甚至可以不传参数。

def hello(name='Anonym', sex='女'):
 	if sex == '男':
 		print("Hello, Mr", name)
	elif sex == '女':
		print("Hello, Miss", name)

hello()  # Hello, Miss Anonym


现在这个函数对于信息不完整的数据也有处理能力了。

4.1.3 函数的返回值

如果将函数比做一名员工,调用函数的我们就是老板,老板给员工一些具体的指示,员工则按规定好的流程去做事。有一些事情,比如老板说去打扫一下厕所,员工就默默地去干活了,干完了就完事了。如果是一些需要回复的事情,比如老板让员工去算一下去年公司的收入,那老板的意思肯定是要知道最后算出来的那个数字。对于函数也是一样,有一些函数我们是需要知道执行的结果。

def multiply(num1, num2):
	return num1 * num2

n = multiply(2, 4)
print(n)  # 8


multiply函数的功能是计算两个数相乘,我们传入两数字作为参数,希望能得到一个这两个数相乘的结 果。multiply的最后一行使用 return 关键字将结果返回。通常在函数的最后一行返回结果,但有时候 也有多种可能。

def permit(age):
   	if age >= 18:
       	print("准许进入")
       	return True
   	else:
       	print("禁止进入")
       	return False

   	print("end")


上面我们定义了一个只允许成年人进入的函数,如果年龄大于等于18岁,返回True,表示允许通过;如果小于18岁则不允许。虽然有两个return语句,但只返回一个结果,要么返回True要么返回False。注 意在return语句执行完后,函数就会结束执行,在它之后的任何语句都不会再执行,所以上例中 的“end”无论怎么样都不会被打印。

如果一个函数内没有任何return语句,那它的返回值就是None。

def do_nothing():
   pass

print(do_nothing())  # None


4.1.4 匿名函数

有时候我们临时需要一个函数,且它的逻辑比较简单,这时候就可以定义匿名函数。

lambda n: n * n


这就定义了一个匿名函数,这个匿名函数接收一个数值参数,计算出这个数的平方值并返回,就相当于下面的函数。

def square(n):
	return n * n


lambda是Python中的关键字,它的作用就是用来定义匿名函数,匿名函数的函数体一般只有一行代 码,省略了函数名和返回值语句。

这样的函数它的作用是什么呢?什么时候需要使用匿名函数而不是函数呢?回忆一下,我们在学习列表排序的时候用过一个匿名函数,现在是时候重温一下了。

revenue = [('1月', 5610000), ('2月', 4850000), ('3月', 6220000)]

revenue.sort(reverse=True, key=lambda x:x[1])


列表的sort函数key参数,它只能接收一个函数类型的值。单独看一下这段匿名函数:

key = lambda x: x[1]


现在key就是一个函数了,我们来调用一下它,x[1]这种索引操作说明x肯定是个序列,且长度至少为2。

key([1, 2])   # 2
key("abcd")  # 'b'


key函数的作用就是返回序列中的第二个元素,在sort排序的时候就会以每个元素的第二个元素作为比对的依据。在这个例子中,第二个元素就是月收入,所以是不是达到了以月收入排序的目的了?

这样的一个简单的功能,我们用不着单独定义一个函数,即用即抛,就像一次性手套一样,这正是匿名函数的使用场景。

第二节 面向对象
4.2.1 面向对象基本概念

做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。

别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。

我先来介绍一下这些东西怎么用,文末抱走。


(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

(4)200多本电子书

这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。

基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。

(5)Python知识点汇总

知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。

在这里插入图片描述

(6)其他资料

还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值