2024年Python最新爆肝六万字整理的python基础,快速入门python的首选

elif else except exec finally for from global

if in import is lambda not or pass

print raise return try while with yield

  1. 起一个有意义的名字,尽量做到看一眼就知道是什么意思(提高代码可 读性) 比如: 名字 就定义为 name ,年龄用age。

  2. 驼峰命名法

第一种 小驼峰式命名法(lower camel case): 第一个单词以小写字母开始;第二个单词的首字母大写,例如:myName、aDog

第二种 大驼峰式命名法(upper camel case): 每一个单字的首字母都采用大写字母,例如:FirstName、LastName

第三种 用下划线“_”来连接所有的单词,比如send_buf,这是python主推的命名方法,叫做snake-case。

驼峰法

驼峰法

注:python中的标识符是区分大小写的

大小写

3.4 常用的数据类型转换


| 函数 | 说明 |

| :-: | :-: |

| int(x [,base ]) | 将x转换为一个整数 |

| long(x [,base ]) | 将x转换为一个长整数 |

| float(x ) | 将x转换到一个浮点数 |

| complex(real [,imag ]) | 创建一个复数 |

| str(x ) | 将对象 x 转换为字符串 |

| repr(x ) | 将对象 x 转换为表达式字符串 |

| eval(str ) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |

| tuple(s ) | 将序列 s 转换为一个元组 |

| list(s ) | 将序列 s 转换为一个列表 |

| chr(x ) | 将一个整数转换为一个字符 |

| unichr(x ) | 将一个整数转换为Unicode字符 |

| ord(x ) | 将一个字符转换为它的整数值 |

| hex(x ) | 将一个整数转换为一个十六进制字符串 |

| oct(x ) | 将一个整数转换为一个八进制字符串 |

举例

a = ‘100’ # 此时a的类型是一个字符串,里面存放了100这3个字符

b = int(a) # 此时b的类型是整型,里面存放的是数字100

print(“a=%d”%b)

4 注释

===============================================================

4.1 单行注释


以#开头,#右边的所有东西当做说明,而不是真正要执行的程序,起辅助说明作用

我是注释,可以在里写一些功能说明之类的哦

print(‘hello world’)

4.2 多行注释


‘’'我是多行注释,可以写很多很多行的

哈哈哈。。。

哈哈哈。。。

‘’’

‘’’

我是多行注释,可以写很多很多行的

哈哈哈。。。

哈哈哈。。。

‘’’

print(‘hello world’)

4.3 编码


如果直接在程序中用到了中文,比如

print(‘你好,我是AI浩’)

如果直接运行输出,程序会出现编码的问题(这和平台有关)

解决的办法为:在程序的开头写入如下代码,这就是中文注释

#coding=utf-8

修改之后的程序:

#coding=utf-8

print(‘你好,我是AI浩’)

运行结果:

你好

注意:在python的语法规范中推荐使用的方式:

-- coding:utf-8 --

5 输入输出

=================================================================

5.1 输入


input()接受表达式输入,并把表达式的结果赋值给等号左边的变量

a = input(“请输入数字:”)

print(a)

print(type(a))

b=input(“请输入字符串:”)

print(b)

print(type(b))

c= input(“请输入数学表达式:”)

print©

print(type©)

d= input(“请输入字符串表达式:”)

print(d)

print(type(d))

运行结果:

请输入数字:123

123

<class ‘str’>

请输入字符串:abc

abc

<class ‘str’>

请输入数学表达式:123+456

123+456

<class ‘str’>

请输入字符串表达式:sdsf,1223

sdsf,1223

<class ‘str’>

5.2 输出


print() 将python的输入

打印提示

print(‘hello world’)

5.2.1 格式化输出


如下代码:

age = 100

print(“我今年%d岁”%age)

age += 1

print(“我今年%d岁”%age)

age += 1

print(“我今年%d岁”%age)

运行结果:

我今年100岁

我今年101岁

我今年102岁

在程序中,看到了%这样的操作符,这就是Python中格式化输出。

age = 18

name = “lifeifei”

print(“我的姓名是%s,年龄是%d”%(name,age))

常用的格式符号

| 格式符号 | 转换 |

| :-: | :-: |

| %c | 字符 |

| %s | 通过str() 字符串转换来格式化 |

| %i | 有符号十进制整数 |

| %d | 有符号十进制整数 |

| %u | 无符号十进制整数 |

| %o | 八进制整数 |

| %x | 十六进制整数(小写字母) |

| %X | 十六进制整数(大写字母) |

| %e | 索引符号(小写’e’) |

| %E | 索引符号(大写“E”) |

| %f | 浮点实数 |

| %g | %f和%e 的简写 |

| %G | %f和%E的简写 |

在python3.6版本中新增了f-string格式化方式,称之为字面量格式化字符串,是新的格式化字符串的语法。

例:

name = ‘AI浩’

print(f’Hello {name}') # 替换变量

运行结果:

Hello AI浩

f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:

dicPeople= {‘name’: ‘AIHao’, ‘Age’: 111}

print(f’{dicPeople[“name”]}: {dicPeople[“Age”]}')

运行结果:

AIHao: 111

用了这种方式明显更简单了,不用再去判断使用 %s,还是 %d。

在 Python 3.8 的版本中可以使用 = 符号来拼接运算表达式与结果:

x=10

print(f"{x+10=}")

运行结果:

x+10=20

5.2.2换行输出

在输出的时候,如果有\n那么,此时\n后的内容会在另外一行显示

print(“1234567890-------”) # 会在一行显示

print(“1234567890\n-------”) # 一行显示1234567890,另外一行显示-------

运行结果:

1234567890-------

1234567890


6 运算符

================================================================

python支持以下几种运算符

  • 算术运算符

下面以a=10 ,b=20为例进行计算

| 运算符 | 描述 | 实例 |

| :-- | :-: | — |

| + | 加 | 两个对象相加 a + b 输出结果 30 |

| - | 减 | 得到负数或是一个数减去另一个数 a - b 输出结果 -10 |

| * | 乘 | 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200 |

| / | 除 | x除以y b / a 输出结果 2 |

| // | 取整除 | 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |

| % | 取余 | 返回除法的余数 b % a 输出结果 0 |

| ** | 幂 | 返回x的y次幂 a**b 为10的20次方, 输出结果 100000000000000000000 |

9/2.0

4.5

9//2.0

4.0

  • 赋值运算符

| 运算符 | 描述 | 实例 |

| :-- | :-: | — |

| = | 赋值运算符 | 把=号右边的结果给左边的变量 num=1+2*3 结果num的值为7 |

a, b = 1, 2

a

1

b

2

  • 复合赋值运算符

| 运算符 | 描述 | 实例 |

| :-- | :-: | — |

| += | 加法赋值运算符 | 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 |

  • 比较(即关系)运算符

python中的比较运算符如下表

| 运算符 | 描述 | 示例 |

| :-- | :-- | :-- |

| == | 检查两个操作数的值是否相等,如果是则条件变为真。 | 如a=3,b=3则(a == b) 为 true. |

| != | 检查两个操作数的值是否相等,如果值不相等,则条件变为真。 | 如a=1,b=3则(a != b) 为 true. |

| <> | 检查两个操作数的值是否相等,如果值不相等,则条件变为真。 | 如a=1,b=3则(a <> b) 为 true。这个类似于 != 运算符 |

| > | 检查左操作数的值是否大于右操作数的值,如果是,则条件成立。 | 如a=7,b=3则(a > b) 为 true. |

| < | 检查左操作数的值是否小于右操作数的值,如果是,则条件成立。 | 如a=7,b=3则(a < b) 为 false. |

| >= | 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件成立。 | 如a=3,b=3则(a >= b) 为 true. |

| <= | 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件成立。 | 如a=3,b=3则(a <= b) 为 true. |

  • 逻辑运算符

| 运算符 | 逻辑表达式 | 描述 | 实例 |

| :-- | :-- | :-- | :-- |

| and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 | (a and b) 返回 20。 |

| or | x or y | 布尔"或" - 如果 x 是 True,它返回 True,否则它返回 y 的计算值。 | (a or b) 返回 10。 |

| not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |

7 判断语句

=================================================================

7.1 if语句


  • if语句是用来进行判断的,其使用格式如下:

if 要判断的条件:

条件成立时,要做的事情

例1:

age = 30

print(“------if判断开始------”)

if age >= 18:

print (“我已经成年了,我可以约妹子了!!!”)

print (“------if判断结束------”)

运行结果:

------if判断开始------

我已经成年了,我可以约妹子了!!!

------if判断结束------

例2:

age = 16

print(“------if判断开始------”)

if age >= 18:

print (“我已经成年了,我可以约妹子了!!!”)

print (“------if判断结束------”)

运行结果:

------if判断开始------

------if判断结束------

**总结:**以上2个例子仅仅是age变量的值不一样,结果却不同;能够看得出if判断语句的作用:就是当满足一定条件时才会执行那块代码,否则就不执行那块代码

7.2 if-else语句


if 条件:

满足条件时要做的事情1

满足条件时要做的事情2

满足条件时要做的事情3

else:

不满足条件时要做的事情1

不满足条件时要做的事情2

不满足条件时要做的事情3

例:

age = 30

print(“------if判断开始------”)

if age >= 18:

print (“我已经成年了,我可以约妹子了!!!”)

else:

print(“还没有成年,不能约妹子!!!”)

print (“------if判断结束------”)

结果1:年龄大于18

------if判断开始------

我已经成年了,我可以约妹子了!!!

------if判断结束------

结果2:年龄小于18

------if判断开始------

还没有成年,不能约妹子!!!

------if判断结束------

7.3 elif


elif的使用格式如下:

if xxx1:

事情1

elif xxx2:

事情2

elif xxx3:

事情3

说明:

  • 当xxx1满足时,执行事情1,然后整个if结束

  • 当xxx1不满足时,那么判断xxx2,如果xxx2满足,则执行事情2,然后整个if结束

  • 当xxx1不满足时,xxx2也不满足,如果xxx3满足,则执行事情3,然后整个if结束

例:

score = 66

if 90 <= score <= 100:

print(‘本次考试,等级为A’)

elif 80 <= score < 90:

print(‘本次考试,等级为B’)

elif 70 <= score < 80:

print(‘本次考试,等级为C’)

elif 60 <= score < 70:

print(‘本次考试,等级为D’)

elif 0 <= score < 60:

print(‘本次考试,等级为E’)

可以和else一起使用

if 性别为男性:

输出男性的特征

elif 性别为女性:

输出女性的特征

else:

第三种性别的特征

说明:

  • 当 “性别为男性” 满足时,执行 “输出男性的特征”的相关代码

  • 当 “性别为男性” 不满足时,如果 “性别为女性”满足,则执行 “输出女性的特征”的相关代码

  • 当 “性别为男性” 不满足,“性别为女性”也不满足,那么久默认执行else后面的代码,即 “第三种性别的特征”相关代码

  • elif必须和if一起使用,否则出错

7.4 if嵌套


if嵌套的格式

if 条件1:

满足条件1 做的事情1

满足条件1 做的事情2

if 条件2:

满足条件2 做的事情1

满足条件2 做的事情2

  • 说明

  • 外层的if判断,也可以是if-else

  • 内层的if判断,也可以是if-else

  • 根据实际开发的情况,进行选择

if嵌套的应用举例:

age = 16

girl = False

if age >= 18:

print(“我已经成年了,我可以约妹子了!!!”)

if girl:

print(“有女朋友,去约会!!”)

else:

print(“没有女朋友,约个屁啊!!”)

else:

print(“还没有成年,不能约妹子!!!”)

if girl:

print(“还没有成年,这是早恋啊!!”)

else:

print(“听话的好孩子!!!”)

结果1:age= 30;girl= True

我已经成年了,我可以约妹子了!!!

有女朋友,去约会!!

结果2:age= 30;girl= False

我已经成年了,我可以约妹子了!!!

没有女朋友,约个屁啊!!

结果3:age= 16;girl= False

还没有成年,不能约妹子!!!

听话的好孩子!!!

结果4:age= 16;girl= True

还没有成年,不能约妹子!!!

还没有成年,这是早恋啊!!

8 循环、break和continue

==============================================================================

8.1 while循环


while 条件:

条件满足时,做的事情1

条件满足时,做的事情2

条件满足时,做的事情3

…(省略)…

例:

i = 0

while i < 5:

print(“当前是第%d次执行循环” % (i + 1))

print(“i=%d” % i)

i += 1

结果:

当前是第1次执行循环

i=0

当前是第2次执行循环

i=1

当前是第3次执行循环

i=2

当前是第4次执行循环

i=3

当前是第5次执行循环

i=4

案例1. 计算1~100的累积和(包含1和100)

参考代码如下:

encoding=utf-8

i = 1

sum = 0

while i <= 100:

sum = sum + i

i += 1

print(“1~100的累积和为:%d” % sum)

运行结果:1~100的累积和为:5050

案例2. 计算1~100之间偶数的累积和(包含1和100)

encoding=utf-8

i = 1

sum = 0

while i <= 100:

if i % 2 == 0:

sum = sum + i

i += 1

print(“1~100的偶数累积和为:%d” % sum)

运行结果:1~100的偶数累积和为:2550

8.2 while循环嵌套


类似if的嵌套,while嵌套就是:while里面还有while

格式如下

while 条件1:

条件1满足时,做的事情1

条件1满足时,做的事情2

while 条件2:

条件2满足时,做的事情1

条件2满足时,做的事情2

条件2满足时,做的事情3

…(省略)…

案例1 要求:打印如下图形:




参考代码:

i = 1

while i<=5:

j = 1

while j<=i:

print("* ",end=‘’)

j+=1

print(“\n”)

i+=1

案例2 :九九乘法表

i = 1

while i<=9:

j=1

while j<=i:

print("%d*%d=%-2d "%(j,i,i*j),end=‘’)

j+=1

print(‘\n’)

i+=1

运行结果:

1*1=1

12=2 22=4

13=3 23=6 3*3=9

14=4 24=8 34=12 44=16

15=5 25=10 35=15 45=20 5*5=25

16=6 26=12 36=18 46=24 56=30 66=36

17=7 27=14 37=21 47=28 57=35 67=42 7*7=49

18=8 28=16 38=24 48=32 58=40 68=48 78=56 88=64

19=9 29=18 39=27 49=36 59=45 69=54 79=63 89=72 9*9=81

8.3 for循环


像while循环一样,for可以完成循环的功能。

在Python中 for循环可以遍历任何序列的项目,如一个列表或者一个字符串等。

格式如下:

for 临时变量 in 列表或者字符串等:

循环满足条件时执行的代码

else:

循环不满足条件时执行的代码

例1:

name = ‘AIHao’

for x in name:

print(x)

运行结果如下:

A

I

H

a

o

案例2:

name = ‘’

for x in name:

print(x)

else:

print(“没有数据”)

运行结果如下:

没有数据

8.5 break


1) for循环

name = ‘AIHao’

for x in name:

print(‘----’)

if x == ‘a’:

break

print(x)

运行结果:


A


I


H


2)while循环

i = 0

while i<10:

i = i+1

print(‘----’)

if i==5:

break

print(i)

运行结果:


1


2


3


4


**总结:**break的作用:用来结束整个循环

8.6 continue


1) for循环

name = ‘AIHao’

for x in name:

print(‘----’)

if x == ‘a’:

continue

print(x)

运行结果:


A


I


H



o

2) while循环

i = 0

while i<10:

i = i+1

print(‘----’)

if i==5:

continue

print(i)

运行结果:


1


2


3


4



6


7


8


9


10

**总结:**continue的作用:用来结束本次循环,紧接着执行下一次的循环

注:

  • break/continue只能用在循环中,除此以外不能单独使用

  • break/continue在嵌套循环中,只对最近的一层循环起作用

9 字符串、列表、元组、字典

=========================================================================

9.1 字符串


1)使用单引号或双引号定义的数据就是字符串,例:

a=‘hello’

或者

a=“hello”

2)字符串的输出使用print()

name = ‘AI浩’

position = ‘算法工程师’

address = ‘北京石景山’

print(‘--------------------------------------------------’)

print(“姓名:%s” % name)

print(“职位:%s” % position)

print(“公司地址:%s” % address)

print(‘--------------------------------------------------’)

运行结果:


姓名:AI浩

职位:算法工程师

公司地址:北京石景山


3)字符串输入

userName = input(‘请输入用户名:’)

print(“用户名为:%s” % userName)

password = input(‘请输入密码:’)

print(“密码为:%s” % password)

结果:(根据输入的不同结果也不同)

请输入用户名:dfsdfsd

用户名为:dfsdfsd

请输入密码:qqq

密码为:qqq

4)下标和切片

下标的使用

name = ‘abcdef’

print(name[0])

print(name[1])

print(name[2])

运行结果:

a

b

c

切片:

切片是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作。

切片的语法:[起始:结束:步长]

注意:选取的区间属于左闭右开型,即从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身)。

name = ‘abcdef’

print(name[0:3]) # 取 下标0~2 的字符

运行结果:

abc

9.2 字符串常见操作

======================================================================

如有字符串mystr = 'hello world AIHao and CSDN',以下是常见的操作

9.2.1 find

检测 str 是否包含在 mystr中,如果是返回开始的索引值,否则返回-1,语法:

mystr.find(str, start=0, end=len(mystr))

例:

mystr = ‘hello world AIHao and CSDN’

print(mystr.find(“AIHao”, 0, len(mystr)))

运行结果:

12

9.2.2 index

跟find()方法一样,只不过如果str不在 mystr中会报一个异常,语法:

mystr.index(str, start=0, end=len(mystr))

例:

mystr = ‘hello world AIHao and CSDN’

print(mystr.index(“Hao”, 0, len(mystr)))

运行结果:

14

9.2.3 count

返回 str在start和end之间 在 mystr里面出现的次数,语法:

mystr.count(str, start=0, end=len(mystr))

例:

mystr = ‘hello world AIHao and CSDN’

print(mystr.count(“a”, 0, len(mystr)))

运行结果:2

9.2.4 replace

把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次,语法:

mystr.replace(str1, str2, mystr.count(str1))

例:

mystr = ‘hello world AIHao and CSDN’

newStr=mystr.replace(“a”,“ee”,mystr.count(“a”))

print(newStr)

运行结果:

hello world AIHeeo eend CSDN

9.2.5 split

以 str 为分隔符切片 mystr,如果 maxsplit有指定值,则仅分隔 maxsplit 个子字符串,语法:

mystr.split(str=" ", 2)

例:

mystr = ‘hello world AIHao and CSDN’

newStr=mystr.split(" ",2)

print(newStr)

运行结果:

[‘hello’, ‘world’, ‘AIHao and CSDN’]

mystr = ‘hello world AIHao and CSDN’

newStr=mystr.split(" ")

print(newStr)

运行结果:

[‘hello’, ‘world’, ‘AIHao’, ‘and’, ‘CSDN’]

9.2.6 capitalize

把字符串的第一个字符大写,其他的变成小写,语法:

mystr.capitalize()

例:

mystr = ‘hello world AIHao and CSDN’

print(mystr.capitalize())

运行结果:

Hello world aihao and csdn

9.2.7 title

把字符串的每个单词首字母大写,其他的改成小写,例:

mystr = ‘hello world AIHao and CSDN’

print(mystr.title())

运行结果:

Hello World Aihao And Csdn

9.2.8 startswith

检查字符串是否是以 obj 开头, 是则返回 True,否则返回 False

mystr.startswith(obj)

例:

mystr = ‘hello world AIHao and CSDN’

ss=‘hello’

print(mystr.startswith(ss))

运行结果:True

9.2.9 endswith

检查字符串是否以obj结束,如果是返回True,否则返回 False,用法同上

mystr.endswith(obj)

9.2.10 lower

转换 mystr 中所有大写字符为小写

mystr.lower()

例:

mystr = ‘hello world AIHao and CSDN’

print(mystr.lower())

运行结果:

hello world aihao and csdn

9.2.11 upper

转换 mystr 中的小写字母为大写,用法同上。

mystr.upper()

9.2.12 ljust

返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串

mystr.ljust(width)

例:

mystr = “hello world AIHao and CSDN”

print(mystr.ljust(50))

运行结果:

hello world AIHao and CSDN

9.2.13 rjust

返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串

mystr.rjust(width)

例:

mystr = “hello world AIHao and CSDN”

print(mystr.rjust(30))

运行结果:

hello world AIHao and CSDN

9.2.14 center

返回一个原字符串居中,并使用空格填充至长度 width 的新字符串,用法同上。

mystr.center(width)

9.2.15 lstrip

删除 mystr 左边的空白字符

mystr.lstrip()

9.2.16 rstrip

删除 mystr 字符串末尾的空白字符

mystr.rstrip()

9.2.17 strip

删除mystr字符串两端的空白字符

a = “\n\t itcast \t\n”

a.strip()

‘itcast’

9.2.18 rfind

类似于 find()函数,不过是从右边开始查找.

mystr.rfind(str, start=0,end=len(mystr) )

9.2.19 rindex

类似于 index(),不过是从右边开始.

mystr.rindex( str, start=0,end=len(mystr))

9.2.20 partition

把mystr以str分割成三部分,str前,str和str后

mystr.partition(str)

9.2.21 rpartition

类似于 partition()函数,不过是从右边开始.

mystr.rpartition(str)

9.2.22 splitlines

按照行分隔,返回一个包含各行作为元素的列表

mystr.splitlines()

9.2.23 isalpha

如果 mystr 所有字符都是字母 则返回 True,否则返回 False

mystr.isalpha()

9.2.24 isdigit

如果 mystr 只包含数字则返回 True 否则返回 False.

mystr.isdigit()

9.2.25 isalnum

如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False

mystr.isalnum()

9.2.26 isspace

如果 mystr 中只包含空格,则返回 True,否则返回 False.

mystr.isspace()

9.2.27 join

将mystr 中每个字符后面插入str,构造出一个新的字符串

mystr.join(str)

例:

str_new=" ".join(_my)

print(str_new)

_new1=‘-’.join(_my)

print(_new1)

运行结果:

my name is AIhao

my-name-is-AIhao

9.3 列表List


列表list用[,…]表示,格式如下:

namesList = [‘xiaoWang’,‘xiaoZhang’,‘xiaoHua’]

9.3.1 for循环遍历list

1)例:

namesList = [‘xiaoWang’, ‘xiaoZhang’, ‘xiaoHua’]

for name in namesList:

print(name)

结果:

xiaoWang

xiaoZhang

xiaoHua

列表推导式

1)普通方式

a = [x for x in range(4)]

print(a)

b = [x for x in range(3, 4)]

print(b)

c = [x for x in range(3, 19)]

print©

d = [x for x in range(3, 19, 2)]

print(d)

运行结果:

[0, 1, 2, 3]

[3]

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

[3, 5, 7, 9, 11, 13, 15, 17]

2)在循环的过程中加入if判断

a = [x for x in range(3, 15) if x % 2 == 0]

print(a)

b = [x for x in range(3, 15) if x % 2 != 0]

print(b)

b = [x for x in range(3, 15)]

print(b)

运行结果:

[4, 6, 8, 10, 12, 14]

[3, 5, 7, 9, 11, 13]

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

3)多个for循环

a = [(x, y) for x in range(3, 5) for y in range(3)]

print(a)

b = [(x, y, z) for x in range(3, 5) for y in range(3) for z in range(4, 6)]

print(b)

运行结果:

[(3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2)]

[(3, 0, 4), (3, 0, 5), (3, 1, 4), (3, 1, 5), (3, 2, 4), (3, 2, 5), (4, 0, 4), (4, 0, 5), (4, 1, 4), (4, 1, 5), (4, 2, 4), (4, 2, 5)]

9.3.2 while循环遍历list

namesList = [‘xiaoWang’, ‘xiaoZhang’, ‘xiaoHua’]

length = len(namesList)

i = 0

while i < length:

print(namesList[i])

i += 1

运行结果:

xiaoWang

xiaoZhang

xiaoHua

9.4 列表的常用操作


列表中存放的数据是可以进行修改的,比如"增"、“删”、“改”"

9.4.1 添加元素("增"append, extend, insert)

append:通过append可以向列表添加元素

例:

#定义变量A,默认有3个元素

A = [‘xiaoWang’,‘xiaoZhang’,‘xiaoHua’]

print(“-----添加之前,列表A的数据-----”)

for tempName in A:

print(tempName)

#提示、并添加元素

temp = input(‘请输入姓名:’)

A.append(temp)

print(“-----添加之后,列表A的数据-----”)

for tempName in A:

print(tempName)

结果:

-----添加之前,列表A的数据-----

xiaoWang

xiaoZhang

xiaoHua

请输入姓名:xiaohei

-----添加之后,列表A的数据-----

xiaoWang

xiaoZhang

xiaoHua

xiaohei

extend:通过extend可以将另一个集合中的元素逐一添加到列表中

a = [1, 2]

b = [3, 4]

a.append(b)

print(a)

a.extend(b)

print(a)

结果:

[1, 2, [3, 4]]

[1, 2, [3, 4], 3, 4]

insert :insert(index, object) 在指定位置index前插入元素object

a = [0, 1, 2]

a.insert(1, 3)

print(a)

结果:

[0, 3, 1, 2]

9.4.2修改元素(“改”)

修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改,例:

#定义变量A,默认有3个元素

A = [‘xiaoWang’,‘xiaoZhang’,‘xiaoHua’]

print(“-----修改之前,列表A的数据-----”)

for tempName in A:

print(tempName)

#修改元素

A[1] = ‘xiaoLu’

print(“-----修改之后,列表A的数据-----”)

for tempName in A:

print(tempName)

结果:

-----修改之前,列表A的数据-----

xiaoWang

xiaoZhang

xiaoHua

-----修改之后,列表A的数据-----

xiaoWang

xiaoLu

xiaoHua

9.4.3 查找元素("查"in, not in, index, count)

所谓的查找,就是看看指定的元素是否存在

in, not in

python中查找的常用方法为:

  • in(存在),如果存在那么结果为true,否则为false

  • not in(不存在),如果不存在那么结果为true,否则false

demo

#待查找的列表

nameList = [‘xiaoWang’,‘xiaoZhang’,‘xiaoHua’]

#获取用户要查找的名字

findName = input(‘请输入要查找的姓名:’)

#查找是否存在

if findName in nameList:

print(‘在字典中找到了相同的名字’)

else:

print(‘没有找到’)

说明:

in的方法只要会用了,那么not in也是同样的用法,只不过not in判断的是不存在

index, count

index和count与字符串中的用法相同

a = [‘a’, ‘b’, ‘c’, ‘a’, ‘b’]

print(a.index(‘a’, 1, 4))

print(a.count(‘b’))

print(a.count(‘d’))

print(a.index(‘a’, 1, 3)) # 注意是左闭右开区间

运行结果:

Traceback (most recent call last):

File “C:/Users/WH/Desktop/Python基础/第一个Python程序.py”, line 5, in

print(a.index(‘a’, 1, 3)) # 注意是左闭右开区间

ValueError: ‘a’ is not in list

3

2

0

9.4.4 删除元素("删"del, pop, remove)

类比现实生活中,如果某位同学调班了,那么就应该把这个条走后的学生的姓名删除掉;在开发中经常会用到删除这种功能。

列表元素的常用删除方法有:

  • del:根据下标进行删除

  • pop:删除最后一个元素

  • remove:根据元素的值进行删除

demo:(del)

movieName = [‘加勒比海盗’,‘骇客帝国’,‘第一滴血’,‘指环王’,‘霍比特人’,‘速度与激情’]

print(‘------删除之前------’)

for tempName in movieName:

print(tempName)

del movieName[2]

print(‘------删除之后------’)

for tempName in movieName:

print(tempName)

结果:

------删除之前------

加勒比海盗

骇客帝国

第一滴血

指环王

霍比特人

速度与激情

------删除之后------

加勒比海盗

骇客帝国

指环王

霍比特人

速度与激情

例:(pop)

movieName = [‘加勒比海盗’,‘骇客帝国’,‘第一滴血’,‘指环王’,‘霍比特人’,‘速度与激情’]

print(‘------删除之前------’)

for tempName in movieName:

print(tempName)

movieName.pop()

print(‘------删除之后------’)

for tempName in movieName:

print(tempName)

结果:

------删除之前------

加勒比海盗

骇客帝国

第一滴血

指环王

霍比特人

速度与激情

------删除之后------

加勒比海盗

骇客帝国

第一滴血

指环王

霍比特人

demo:(remove)

movieName = [‘加勒比海盗’,‘骇客帝国’,‘第一滴血’,‘指环王’,‘霍比特人’,‘速度与激情’]

print(‘------删除之前------’)

for tempName in movieName:

print(tempName)

movieName.remove(‘指环王’)

print(‘------删除之后------’)

for tempName in movieName:

print(tempName)

结果:

------删除之前------

加勒比海盗

骇客帝国

第一滴血

指环王

霍比特人

速度与激情

------删除之后------

加勒比海盗

骇客帝国

第一滴血

霍比特人

速度与激情

9.4.5 排序(sort, reverse)

sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小。

reverse方法是将list逆置。

a = [1, 4, 2, 3]

a

[1, 4, 2, 3]

a.reverse()

a

[3, 2, 4, 1]

a.sort()

a

[1, 2, 3, 4]

a.sort(reverse=True)

a

[4, 3, 2, 1]

9.4.6 列表的嵌套

类似while循环的嵌套,列表也是支持嵌套的

一个列表中的元素又是一个列表,那么这就是列表的嵌套

schoolNames = [[‘北京大学’,‘清华大学’],

[‘南开大学’,‘天津大学’,‘天津师范大学’],

[‘山东大学’,‘中国海洋大学’]]

案例:一个学校,有3个办公室,现在有8位老师等待工位的分配,请编写程序,完成随机的分配

#encoding=utf-8

import random

定义一个列表用来保存3个办公室

offices = [[],[],[]]

定义一个列表用来存储8位老师的名字

names = [‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’]

i = 0

for name in names:

index = random.randint(0,2)

offices[index].append(name)

i = 1

for tempNames in offices:

print(‘办公室%d的人数为:%d’%(i,len(tempNames)))

i+=1

for name in tempNames:

print(“%s”%name,end=‘’)

print(“\n”)

print(“-”*20)

运行结果如下:

办公室1的人数为:3

BFG


办公室2的人数为:5

ACDEH


办公室3的人数为:0


9.5 元组


Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号(),列表使用方括号[],例:

aTuple = (‘et’,77,99.9)

print(aTuple)

运行结果:(‘et’, 77, 99.9)

9.5.1 访问元组

aTuple = (‘et’,77,99.9)

print(aTuple[0])

print(aTuple[1])

运行结果:

et

77

9.5.2 修改元组

aTuple = (‘et’,77,99.9)

aTuple[0]=111

运行结果:

Traceback (most recent call last):

File “C:/Users/WH/Desktop/Python基础/第一个Python程序.py”, line 2, in

aTuple[0]=111

TypeError: ‘tuple’ object does not support item assignment

从上面的运行结果可以得出: python中不允许修改元组的数据,包括不能删除其中的元素。

9.5.3 元组的内置函数count, index

index和count与字符串和列表中的用法相同

a = (‘a’, ‘b’, ‘c’, ‘a’, ‘b’)

a.index(‘a’, 1, 3) # 注意是左闭右开区间

Traceback (most recent call last):

File “”, line 1, in

ValueError: tuple.index(x): x not in tuple

a.index(‘a’, 1, 4)

3

a.count(‘b’)

2

a.count(‘d’)

0

9.6 字典


字典是一种可变容器模型,且可存储任意类型对象。

字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,格式如下所示:

d = {key1 : value1, key2 : value2, key3 : value3 }

新建 Microsoft Visio 绘图

例:

info = {‘name’:‘AI浩’, ‘id’:100, ‘sex’:‘f’, ‘address’:‘中国北京’}

9.6.1 根据键访问值

info = {‘name’:‘AI浩’, ‘id’:100, ‘sex’:‘f’, ‘address’:‘中国北京’}

print(info[‘name’])

print(info[‘address’])

结果:

AI浩

中国北京

若访问不存在的键,则会报错:

info = {‘name’: ‘AI浩’, ‘id’: 100, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

print(info[‘age’])

运行结果:

Traceback (most recent call last):

File “C:/Users/WH/Desktop/Python基础/第一个Python程序.py”, line 2, in

print(info[‘age’])

KeyError: ‘age’

在我们不确定字典中是否存在某个键而又想获取其值时,可以使用get方法,还可以设置默认值:

age = info.get(‘age’)

age #'age’键不存在,所以age为None

type(age)

<type ‘NoneType’>

age = info.get(‘age’, 18) # 若info中不存在’age’这个键,就返回默认值18

age

18

9.7 字典的常用操作


9.7.1 修改元素

字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改,例:

info = {‘name’: ‘AI浩’, ‘id’: 100, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

info[‘id’] = 150

print(‘修改之后的id为:%d’ % info[‘id’])

结果:修改之后的id为:150

9.7.2 添加元素

使用 变量名[‘键’] = 数据 时,这个“键”在字典中,不存在,那么就会新增这个元素,例:

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

newId = input(‘请输入新的ID’)

info[‘id’] = int(newId)

print(‘添加之后的id为:%d’ % info[‘id’])

结果:

请输入新的ID123

添加之后的id为:123

9.7.3 删除元素

对字典进行删除操作,有一下几种:

  • del

  • clear()

例1:del删除指定的元素

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

print(‘删除前,%s’ % info[‘name’])

del info[‘name’]

print(‘删除后,%s’ % info[‘name’])

结果:

删除前,AI浩

Traceback (most recent call last):

File “C:/Users/WH/Desktop/Python基础/第一个Python程序.py”, line 4, in

print(‘删除后,%s’ % info[‘name’])

KeyError: ‘name’

例2:del删除整个字典

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

print(‘删除前,%s’ % info)

del info

print(‘删除后,%s’ % info)

运行结果:

Traceback (most recent call last):

File “C:/Users/WH/Desktop/Python基础/第一个Python程序.py”, line 4, in

print(‘删除后,%s’ % info)

NameError: name ‘info’ is not defined

删除前,{‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

例3:clear清空整个字典

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

print(‘清空前,%s’ % info)

info.clear()

print(‘清空后,%s’ % info)

运行结果:

清空前,{‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

清空后,{}

9.7.4 字典的长度

使用len()方法,求字典的长度,例:

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

print(‘字典的长度:%d’ % len(info))

运行结果:字典的长度:3

9.7.5 找出字典中的所有key

keys返回一个包含字典所有KEY的视图对象,例:

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

dicKeys=info.keys()

print(dicKeys)

print(dicKeys[0])

运行结果:

Traceback (most recent call last):

File “C:/Users/WH/Desktop/Python基础/第一个Python程序.py”, line 4, in

print(dicKeys[0])

TypeError: ‘dict_keys’ object is not subscriptable

dict_keys([‘name’, ‘sex’, ‘address’])

注:返回的是个视图对象,不是list,很多资料说list是不对的,但是可以转为list,例:

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

dicKeys=list(info.keys())

print(dicKeys)

print(dicKeys[0])

运行结果:

[‘name’, ‘sex’, ‘address’]

name

9.7.6 找出字典所有的value

属性values返回一个包含字典所有value的视图列表,用法同上,例:

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

dicvalues=list(info.values())

print(dicvalues)

print(dicvalues[0])

运行结果:

[‘AI浩’, ‘f’, ‘中国北京’]

AI浩

9.7.7 找出字典的(键,值)

属性items,返回一个包含所有(键,值)元祖的列表

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

dicItems=info.items()

print(dicItems)

运行结果:

dict_items([(‘name’, ‘AI浩’), (‘sex’, ‘f’), (‘address’, ‘中国北京’)])

9.7.8 判断key是否存在

“key in dict"如果键在字典dict里返回true,否则返回false,例:

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

ss=‘name’ in info

print(ss)

运行结果:True

9.7.9 遍历字典的几种方式

1) 遍历字典的key(键)

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

for key in info.keys():

print(key)

运行结果:

name

sex

address

2) 遍历字典的value(值)

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

for key in info.values():

print(key)

运行结果:

AI浩

f

中国北京

3) 遍历字典的项(元素)

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

for item in info.items():

print(item)

运行结果:

(‘name’, ‘AI浩’)

(‘sex’, ‘f’)

(‘address’, ‘中国北京’)

4) 遍历字典的key-value(键值对)

info = {‘name’: ‘AI浩’, ‘sex’: ‘f’, ‘address’: ‘中国北京’}

for key, value in info.items():

print(“key=%s,value=%s” % (key, value))

运行结果:

key=name,value=AI浩

key=sex,value=f

key=address,value=中国北京

10 函数

================================================================

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

10.1 定义函数


语法:

def 函数名(参数列表):

函数体

例:

定义一个函数,能够完成打印信息的功能

def printInfo():

print (‘------------------------------------’)

print (’ 人生苦短,我用Python’)

print (‘------------------------------------’)

定义函数的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()

  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

  • 函数内容以冒号 : 起始,并且缩进。

  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

10.2 调用函数


定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它

调用函数很简单的,通过 函数名() 即可完成调用,例:

定义完函数后,函数是不会自动执行的,需要调用它才可以

printInfo()

10.3 函数的注释


在函数定义下面使用'''进行注释,使用help函数可以查看函数的注释。

def test(a1, a2):

‘’’

用来完成对2个数求和"

:param a1:第一个参数

:param a2:第二个参数

:return:无

‘’’

print(“%d” % (a1 + a2))

print(help(test))

运行结果:

test(a1, a2)

用来完成对2个数求和"

:param a1:第一个参数

:param a2:第二个参数

:return:无

None

10.4 函数的参数


10.4.1 参数的定义

​ 参数分形参、实参

形参:函数定义时括号内的参数

实参:函数调用时括号内的参数

形参相当于变量,实参相当于变量的值。

def add2num(a, b):

c = a + b

print©

add2num(11, 22) # 调用带有参数的函数时,需要在小括号中,传递数据

a,b为形参;11,12为实参

形参:

只在被调用时,才分配内存单元。调用结束,立刻释放所分配的内存。

只在函数内部有效。

实参:

可以是:常量、变量、表达式、函数。

进行函数调用时,实参必须是确定的值。

10.4.2 参数的分类

Python的函数除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。

1)位置参数

位置形参:函数定义时,从左往右写的参数,比如上面的 a, b

位置实参:函数调用时,从左往右写的参数, 比如上面的 11,12

位置形参定义多少个,调用时位置实参必须写上多少个,多一个少一个都不行。

2)关键参数:

正常情况下,给函数传参数,要按顺序。如果不想按顺序,就用关键参数。

指定参数名的参数,就叫做关键参数。

函数调用时:func(a=1, b=2), 这种指定了参数名的参数,就是关键参数。

调用函数时,关键参数可以和位置参数一起用,但是关键参数必须在位置参数的后面。不然会报错。

例:

def add2num(a, b):

c = a + b

print©

#正确的调用方式

add2num(11, b=22) # 调用带有参数的函数时,需要在小括号中,传递数据

add2num(a=11, b=22)

add2num(b=11, a=22)

错误的调用方式。

#add2num(22, a=22)

#add2num(b=11,22)

3)默认参数

函数定义时,默认参数必须在位置形参的后面。

函数调用时,指定参数名的参数,叫关键参数。

而在函数定义时,给参数名指定值的时候,这个参数叫做默认参数。

关键参数,和默认参数两个参数写法一样,区别在于:

关键参数是在函数调用时,指定实参的参数名,也可以说指定值的参数名。

默认参数是在函数定义时,指定参数名的值。

定义时,有默认参数的话,调用时,这个实参可以不写。如果实参不写的话,这个形参的参数值是他的默认值。

例:

def add2num(a, b=100):

c = a + b

print©

add2num(11, b=22) # 调用带有参数的函数时,需要在小括号中,传递数据

add2num(11)

运行结果:

33

111

4 ) 动态参数:*args **kwargs

*args

针对函数定义时的*:

def func(a, b, *args):

pass

*args会接收函数调用时,传入的多余的位置实参。

*args 是一个元组

例子:

func(1, 2, 3, 4, 5, 6) 函数调用,因为函数定义时,*args前面有形参a, 形参b, *args就接收调用时多余的位置实参

a为1, b为2, *args 为: (3, 4, 5, 6),是一个元组。

针对函数调用时的 *:

func(1, 2, *[1, 2, 3, 4]) == func(1, 2, 1, 2, 3, 4)

函数调用时有*, 就应该立马将*后面的列表,元组,字符串之类的迭代器,打散成位置参数来看。

注意,如果 *后面是一个字典的话,那么打散成的位置参数就是字典的key

*可以看做是for循环。

形参中 *args 只能接收多余的位置实参,成为一个元组。不能接收关键实参。

例:

def calc(*numbers):

sum = 0

for n in numbers:

sum = sum + n * n

return sum

nums = [1, 2, 3]

调用方式1

print(calc(nums[0], nums[1], nums[2]))

#调用方式2

print(calc(*nums))

运行结果:

14

14

**kwargs:

针对函数定义时,站在形参的角度看 **:

接收多余的关键实参,成为一个字典dict。

字典的key是关键实参的变量名,字典的value是关键实参的值。

将字典交给**后面的变量名,这里是kwargs

站在实参的角度看 ** :

d = {‘x’:1, ‘y’:2, ‘z’:333}

func(**d) # 等价于func(x=1,y=2,z=333)

函数调用时,后面可以接一个字典,然后会把字典打散成关键参数的形式,也就是key=value的形式。

例:

def person(name, age, **kw):

print(‘name:’, name, ‘age:’, age, ‘other:’, kw)

#调用方式1

print(person(‘Michael’, 30))

#调用方式2

print(person(‘Bob’, 35, city=‘Beijing’))

#调用方式3

print(person(‘Adam’, 45, gender=‘M’, job=‘Engineer’))

运行结果:

name: Michael age: 30 other: {}

None

name: Bob age: 35 other: {‘city’: ‘Beijing’}

None

name: Adam age: 45 other: {‘gender’: ‘M’, ‘job’: ‘Engineer’}

None

5)混合参数时,参数顺序

函数定义时:

从左往右:位置形参 > *args > 默认参数 > **kwargs

位置形参 > 默认参数 > *args > **kwargs 也可以。

因为函数调用时给的实参满足了位置形参、默认参数之后,会把多余的位置实参给args。这样并不会报错。

但是 **kwargs 必须在 *args后面

默认形参必须在位置形参后面

​ 函数调用时:

从左到右:位置实参 > *args > 关键参数 > **kwargs

因为 * args 在函数调用时,会被打散成位置实参,而关键参数必须在位置实参的后面,否则会报错。SyntaxError: positional argument follows keyword argument

*args 必须在 **kwargs后面, 否则会报语法错误:SyntaxError: iterable argument unpacking follows keyword argument unpacking

总结

Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。

默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!

要注意定义可变参数和关键字参数的语法:

*args是可变参数,args接收的是一个tuple;

**kw是关键字参数,kw接收的是一个dict。

以及调用函数时如何传入可变参数和关键字参数的语法:

可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3))

关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})

使用*args**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。

命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。

定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。

10.4.3 参数的传递

Python参数传递采用的肯定是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值’来传递对象。

例:

attrList = [0, 1, 2, 3, 4, 5]

print(“改变前————————————————————————————————”)

print(attrList)

def func(i, attrList):

attrList[i] = attrList[i] * 10

print(“改变后————————————————————————————————”)

for i in range(3):

func(i, attrList)

print(attrList)

运行结果:

改变前————————————————————————————————

[0, 1, 2, 3, 4, 5]

改变后————————————————————————————————

[0, 10, 20, 3, 4, 5]

可以看到,List发生了改变,如果传入不可变的元素呢?

a = 10

print(“改变前————————————————————————————————”)

print(a)

def func©:

print(id©)

c += 2

print(id©)

print(“func函数的c值:”, c)

print(id(a))

func(a)

print(“改变后————————————————————————————————”)

print(a)

print(id(a))

运行结果:

改变前————————————————————————————————

10

140724141828160

140724141828160

140724141828224

func函数的c值: 12

改变后————————————————————————————————

10

140724141828160

将a变量作为参数传递给了func函数,传递了a的一个引用,把a的地址传递过去了,所以在函数内获取的变量c的地址跟变量a的地址是一样的,但是在函数内,对c进行赋值运算,c的值从10变成了12,实际上10和12所占的内存空间都还是存在的,赋值运算后,c指向12所在的内存。而a仍然指向10所在的内存,所以后面打印a,其值还是10.

10.5 函数的返回值


想要在函数中把结果返回给调用者,需要在函数中使用return,例:

def add2num(a, b):

c = a + b

return c

print(add2num(1, 2))

可以返回多个返回值,例:

def divid(a, b):

shang = a // b

yushu = a % b

return shang, yushu

sh, yu = divid(5, 2)

10.6 局部变量与全局变量


  • 局部变量就是定义在一个函数体内部的变量

  • 全局变量是定义在外面的变量

例:

a = 1

def f():

b = 2

其中a就是全局变量,而b是局部变量。局部变量只在函数体内部有效,出了函数体,外面是访问不到的,而全局变量则对下面的代码都有效。

全局变量可以直接在函数体内容部使用的,你可以直接访问,但是注意的是,如果对于不可变类型的数据,如果在函数里面进行了赋值操作,则对外面的全局变量不产生影响,因为相当于新建了一个局部变量,只是名字和全局一样,而对于可变类型,如果使用赋值语句,同样对外部不产生影响,但是使用方法的话就会对外部产生影响。

g_b = 3

g_l1 = [1, 2]

g_l2 = [1, 2, 3]

def t1():

g_b = 2

g_l1 = []

g_l2.append(7)

t1()

print(g_b, g_l1, g_l2)

运行结果:3 [1, 2] [1, 2, 3, 7]

global关键字

上面说到,如果使用的是赋值语句,在函数内部相当于新建了一个变量,并且重新给了指向,但是有时候我们想把这个变量就是外部的那个全局变量,在赋值操作的时候,就是对全局变量给了重新的指向,这个时候可以通过global关键字表示我在函数里面的这个变量是使用的全局那个。使用方法如下:

g_b = 3

def t1():

global g_b

g_b = 2

t1()

print(g_b)

运行结果:2

这个时候你会发现全局变量g_b也重新指向了,这是因为global g_b表示指定了函数中的g_b就是外面的那个。

10.7 递归函数


如果一个函数在内部调用自身本身,这个函数就是递归函数。例:

def fact(n):

if n == 1:

return 1

return n * fact(n - 1)

print(fact(5))

运行结果:120

可以根据函数定义看到计算过程如下:

===> fact(5)

===> 5 * fact(4)

===> 5 * (4 * fact(3))

===> 5 * (4 * (3 * fact(2)))

===> 5 * (4 * (3 * (2 * fact(1))))

===> 5 * (4 * (3 * (2 * 1)))

===> 5 * (4 * (3 * 2))

===> 5 * (4 * 6)

===> 5 * 24

===> 120

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000)。

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

上面的fact(n)函数由于return n * fact(n - 1)引入了乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中,例:

def fact(n):

return fact_iter(n, 1)

def fact_iter(num, product):

if num == 1:

return product

return fact_iter(num - 1, num * product)

可以看到,return fact_iter(num - 1, num * product)仅返回递归函数本身,num - 1和num * product在函数调用前就会被计算,不影响函数调用。

fact(5)对应的fact_iter(5, 1)的调用如下:

===> fact_iter(5, 1)

===> fact_iter(4, 5)

===> fact_iter(3, 20)

===> fact_iter(2, 60)

===> fact_iter(1, 120)

===> 120

尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。

小结

使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。

Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

10.8 匿名函数


10.8.1 定义

用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。

lambda函数的语法只包含一个语句,如下:

lambda [arg1 [,arg2,…argn]]:expression

如下实例:

sum = lambda a1, a2: a1 * a2

调用sum函数

print("Value of total : ", sum(10, 20))

print("Value of total : ", sum(20, 20))

以上实例输出结果:

Value of total : 200

Value of total : 400

Lambda函数能接收任何数量的参数但只能返回一个表达式的值

匿名函数不能直接调用print,因为lambda需要一个表达式

10.8.2 应用场合

例1:自己定义函数作为参数传递

def fun(a, b, opt):

print(“a =”, a)

print(“b =”, b)

print(“result =”, opt(a, b))

fun(1, 2, lambda x, y: x + y)

运行结果:

a = 1

b = 2

result = 3

例2:作为内置函数的参数

想一想,下面的数据如何指定按age或name排序?

stus = [

{“name”:“zhangsan”, “age”:18},

{“name”:“lisi”, “age”:19},

{“name”:“wangwu”, “age”:17}

]

按name排序:

stus.sort(key=lambda x: x[‘name’])

print(stus)

运行结果:

[{‘name’: ‘lisi’, ‘age’: 19}, {‘name’: ‘wangwu’, ‘age’: 17}, {‘name’: ‘zhangsan’, ‘age’: 18}]

按age排序:

stus.sort(key=lambda x: x[‘age’])

print(stus)

运行结果:

[{‘name’: ‘wangwu’, ‘age’: 17}, {‘name’: ‘zhangsan’, ‘age’: 18}, {‘name’: ‘lisi’, ‘age’: 19}]

11 文件操作

==================================================================

11.1 打开与关闭


11.1.1 打开文件

在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件

open(文件名,访问模式)

示例如下:

f = open(‘test.txt’, ‘w’)

说明:

| 访问模式 | 说明 |

| :-: | :-- |

| r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |

| w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |

| a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |

| rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |

| wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |

| ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |

| r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |

| w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |

| a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |

| rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |

| wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |

| ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |

11.1.2 关闭文件

close( )

示例如下:

新建一个文件,文件名为:test.txt

f = open(‘test.txt’, ‘w’)

关闭这个文件

f.close()

11.2 文件的读写


11.2.1 写数据(write)

使用write()可以完成向文件写入数据,例:

f = open(‘test.txt’, ‘w’)

f.write(‘hello 大家好, 我是AI浩’)

f.close()

运行现象:

image-20210831144255382

注意:

  • 如果文件不存在那么创建,如果存在那么就先清空,然后写入数据

11.2.2 读数据(read)

使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据,例:

f = open(‘test.txt’, ‘r’)

content = f.read(5)

print(content)

print(“-”*30)

content = f.read()

print(content)

f.close()

运行结果:

hello


大家好, 我是AI浩

注意:

  • 如果open是打开一个文件,那么可以不用谢打开的模式,即只写 open('test.txt')

  • 如果使用读了多次,那么后面读取的数据是从上次读完后的位置开始的

11.2.3 读数据(readlines)

就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素

#coding=utf-8

f = open(‘test.txt’, ‘r’)

content = f.readlines()

print(type(content))

i=1

for temp in content:

print(“%d:%s”%(i, temp))

i+=1

f.close()

运行结果:

<class ‘list’>

1:hello 大家好, 我是AI浩

11.2.4 读数据(readline)

#coding=utf-8

f = open(‘test.txt’, ‘r’)

content = f.readline()

print(“1:%s”%content)

content = f.readline()

print(“2:%s”%content)

f.close()

运行结果:

1:hello 大家好, 我是AI浩

2:asfsifhiudh

11.3 文件的常用操作


11.3.1 获取当前读写的位置

在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取,例:

打开一个已经存在的文件

f = open(“test.txt”, “r”)

str = f.read(3)

print("读取的数据是 : ", str)

查找当前位置

position = f.tell()

print("当前文件位置 : ", position)

str = f.read(3)

print("读取的数据是 : ", str)

查找当前位置

position = f.tell()

print("当前文件位置 : ", position)

f.close()

运行结果:

读取的数据是 : hel

当前文件位置 : 3

读取的数据是 : lo

当前文件位置 : 6

11.3.2 定位到某个位置

如果在读写文件的过程中,需要从另外一个位置进行操作的话,可以使用seek()

seek(offset, from)有2个参数

  • offset:偏移量

  • from:方向

  • 0:表示文件开头

  • 1:表示当前位置

  • 2:表示文件末尾

例1:把位置设置为:从文件开头,偏移5个字节

打开一个已经存在的文件

f = open(“test.txt”, “r”)

str = f.read(30)

print("读取的数据是 : ", str)

查找当前位置

position = f.tell()

print("当前文件位置 : ", position)

重新设置位置

f.seek(5, 0)

查找当前位置

position = f.tell()

print("当前文件位置 : ", position)

f.close()

例2:把位置设置为:离文件末尾,3字节处

打开一个已经存在的文件

f = open(“test.txt”, “rb”)

print("读取的数据是 : ", str)

position = f.tell()

print("当前文件位置 : ", position)

重新设置位置

f.seek(-3, 2)

读取到的数据为:文件最后3个字节数据

str = f.read()

print("读取的数据是 : ", str)

f.close()

运行结果:

读取的数据是 : <class ‘str’>

当前文件位置 : 0

读取的数据是 : b’ddf’

11.3.3 文件重命名

os模块中的rename()可以完成对文件的重命名操作

rename(需要修改的文件名, 新的文件名)

import os

os.rename(“test.txt”, “test-1.txt”)

11.3.4 删除文件

os模块中的remove()可以完成对文件的删除操作

remove(待删除的文件名)

import os

os.remove(“test.txt”)

11.4 文件夹的相关操作


实际开发中,有时需要用程序的方式对文件夹进行一定的操作,比如创建、删除等

就像对文件操作需要os模块一样,如果要操作文件夹,同样需要os模块

11.4.1 创建文件夹

import os

os.mkdir(“aa”)

11.4.2 获取当前目录

import os

os.getcwd()

11.4.3 改变默认目录

import os

os.chdir(“…/”)

11.4.4 获取目录列表

import os

os.listdir(“./”)

11.4.5 删除文件夹

import os

os.rmdir(“张三”)

11.4.6 检测文件夹是否存在

import os

if not os.path.exists(path):
文末有福利领取哦~

👉一、Python所有方向的学习路线

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

👉二、Python必备开发工具

img
👉三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
img

👉 四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
img

👉五、Python练习题

检查学习结果。
img

👉六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
img

img

👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传

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

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

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

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值