python基础语法

开发环境安装介绍

python是什么?

简单易学、免费开源、流行火爆、应用领域广的语言

龟叔希望有一种语言能像C那样调用计算机功能接口,同时可以像shell那样轻松编程。于是创造了Python

python能干什么?★

继续拓展

  • 自动化测试、运维
  • web开发
  • 网络爬虫
  • 数据分析
  • 桌面软件
  • 科学计算
  • 服务器软件(网络软件)
  • 游戏
  • 人工智能
  • 机器学习

基于python开发的框架:

  • Google开源机器学习框架:TensorFlow
  • 开源社区主推学习框架:Scikit-learn
  • 百度开源深度学习框架:Paddle

怎么学习python?

image-20230922105344921

Python解释器

用来运行文件,其实本质和jvm(Java虚拟机)一样,都是用来解释高级语言的。
有好几种:

  • CPython:C语言开发的解释器[官方],应用广泛
  • IPython,基于CPython的一种交互式解释器。

其他解释器

  • PyPy,基于Python语言开发的解释器。
  • Jython,运行在Java平台的解释器,直接把Python代码编译成Java字节码执行。
  • IronPython,运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

下载:https://www.python.org/downloads/

1
2
注意点:
添加到环境变量path,如果有取消path长度限制选项,也可以选择。

PyCharm

1
功能参考idea,用就完事了。

下载:https://www.jetbrains.com/pycharm/download/

基本使用: 见笔记:工具/编程工具/pycharm/PyCharm安装下载使用

变量

注释

1
2
3
4
5
6
7
8
9
10
11
12
# 注释内容
"""
    第一行注释
    第二行注释
    第三行注释
"""
'''
    注释1
    注释2
    注释3
'''
ps: 快捷键:ctrl+/

变量

变量就是一个存储数据的时候当前数据所在的内存地址的名字而已。

1
2
3
4
5
# 标识符
1.由数字、字母、下划线组成
2.不能数字开头
3.不能使用内置关键字
4.严格区分大小写

image-20230927183515367

1
2
3
4
5
# 命名约定
1.见名知义。
2.大驼峰:即每个单词首字母都大写,例如:MyName。
3.小驼峰:第二个(含)以后的单词首字母大写,例如:myName。
4.下划线:例如:my_name。

关键字

不能用关键字作为变量名,也不要使用python一定义的功能函数的名字,会改变原来的功能,比如print=1,打印功能就无法使用了

查看关键字

1
2
3
4
5
6
import keyword

print(keyword.kwlist) # 打印所有关键字
'''
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
'''

数据类型

数据类型

image-20230927183524368

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
a = 1
print(type(a))  # <class 'int'> -- 整型

b = 1.1
print(type(b))  # <class 'float'> -- 浮点型

c = True
print(type(c))  # <class 'bool'> -- 布尔型

d = '12345'
print(type(d))  # <class 'str'> -- 字符串
ps: "12345" 也是字符串

e = [10, 20, 30]
print(type(e))  # <class 'list'> -- 列表 list []

f = (10, 20, 30)
print(type(f))  # <class 'tuple'> -- 元组 tuple ()

h = {10, 20, 30}
print(type(h))  # <class 'set'> -- 集合 set {}

g = {'name': 'TOM', 'age': 20}
print(type(g))  # <class 'dict'> -- 字典 dict {}

检测数据类型的方法:type()

格式化输出

格式符号 转换
%s 字符串
%d 有符号的十进制整数
%f 浮点数
%c 字符
%u 无符号的十进制整数
%o 八进制整数
%x 十六进制整数(小写ox)
%X 十六进制整数(大写OX)
%e 科学计数法(小写’e’)
%E 科学计数法(大写’E’)
%g %f和%e的简写
%G %f和%E的简写
1
2
3
4
5
6
7
8
9
10
11
# 技巧
%d 以整数输出
%3d 输出时,数据占3个字符宽度,前面是空白符
%03d 输出时,数据占3个字符宽度 ,当数字不足三个字符时,前缀补0 001
%06d 输出的整数显示位数,不足以0补全,超出当前位数则原样输出
%-3d 输出时,数据占3个字符宽度,左对齐,后面是空白符
%f 以小数输出
%.3f 小数点后保留位数是3位
%.2f 小数点后显示的小数位数。
%s,除了可以格式化字符串,还可以格式化浮点数和整数

image-20230927183531861

转义字符

1
2
\n:换行。
\t:制表符,一个tab键(4个空格)的距离。

image-20230927183537136

结束符

1
2
3
为什么两个print会换行输出?
print('输出的内容', end="\n")
在Python中,print(), 默认自带end="\n"这个换行结束符,所以导致每两个print直接会换行展示,用户可以按需求更改结束符。

image-20230927183542098

输入

1
2
input("提示信息") # 类似Java中是scanner
input 接收的任何数据默认都是字符串数据类型(要当成数字做加法的时候要注意类型转换下)

image-20230927183546238

数据类型转换

1
2
为什么要转换?
上面input默认输入得到的是字符串.输入数字也是字符串.所以要转换。

image-20230927184535404

使用的例子:

image-20230927183552273

1
ps: eval 转换为原本的类型,比如e 是字符串,但是它里面的值是整形。就转为整形

image-20230927183557502

运算符

运算符

image-20230927183603622

1
2
ps:**的优先级比*要高。混合运算的时候,最好加上括号,避免优先级搞错了
变量可以多个同时赋值:num1, float1, str1 = 10, 0.5, 'hello world'

image-20230927183608990

1
2
3
4
ps: 
a = 10
a *= 1 + 2 # 30
计算顺序是:先计算"复合赋值运算符" 右边的表达式,再计算 *=

image-20230927183615651

image-20230927183621185

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
a = 1
b = 2
c = 3
print((a < b) and (b < c))  # True
print((a > b) and (b < c))  # False
print((a > b) or (b < c))   # True
print(not (a > b))          # True

# 数字之间的逻辑运算
a = 0
b = 1
c = 2

0就为真!!!0就为假!!!
# and运算符,只要有一个值为0,则结果为0,否则结果为最后一个非0数字
print(a and b)  # 0
print(b and a)  # 0
print(a and c)  # 0
print(c and a)  # 0
print(b and c)  # 2
print(c and b)  # 1

# or运算符,只有所有值为0结果才为0,否则结果为第一个非0数字
print(a or b)  # 1
print(a or c)  # 2
print(b or c)  # 1

流程控制 if 语句

if语句

1
2
3
4
5
6
7
8
9
10
11
12
13
if 条件1:
    print('条件1成立执行的代码1')
    print('条件1成立执行的代码2')
elif 条件2
    条件2成立执行的代码1
    条件2成立执行的代码2
    ......
......
else:
    以上条件都不成立执行执行的代码

# 下方的代码没有缩进到if语句块,所以和if条件无关
print('我是无论条件是否成立都要执行的代码')

image-20230927183627280

1
ps:拓展:age >= 18 and age <= 60可以化简为18 <= age <= 60

嵌套if

1
2
3
4
5
6
7
if 条件1
    条件1成立执行的代码
    条件1成立执行的代码
    
if 条件2
    条件2成立执行的代码
    条件2成立执行的代码

random随机使用

  • 练习:猜拳,随机
1
2
3
4
5
6
7
8
9
10
11
import random
# 猜拳
pc = random.randint(1,3) # Return random integer in range [a, b], including both end points.
print(pc)
man = int(input('请选择出拳:石头(1)剪刀(2)布(3):'))
if (pc == 1 and man == 3) or (pc == 2 and man == 1) or (pc == 3 and man == 2):
    print('玩家获胜')
elif pc == man:
    print('平局')
else:
    print('电脑获胜')

三目运算符

1
2
1 if 条件 else2
条件成立返回左边的值1,不成立返回右边的值2 

流程控制 while循环

while 循环

1
2
3
4
5
6
# 语法
while 条件:
    条件成立重复执行的代码1
    条件成立重复执行的代码2
    ......
ps:python 中没有i++语法,用i+=1代替

break 和 continue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
break:退出循环不执行,如果是嵌套循环,跳出最近的一个循环
continue:跳过当前循环继续执行

i = 1
while i <= 5:
    if i == 4:
        print(f'吃饱了不吃了')
        break
    print(f'吃了第{i}个苹果')
    i += 1

i = 1
while i <= 5:
    if i == 3:
        print(f'大虫子,第{i}个不吃了')
        # 在continue之前一定要修改计数器,否则会陷入死循环
        i += 1
        continue
    print(f'吃了第{i}个苹果')
    i += 1
或者这样写也可以少写一个修改计数器的代码
i = 0 # 赋值0
while i < 5:
    i += 1 # 先修改
    if i == 3:
        print(f'大虫子,第{i}个不吃了')
        continue
    print(f'吃了第{i}个苹果')

嵌套while循环

1
2
3
4
5
6
while 条件1:
    条件1成立执行的代码
    ......
    while 条件2:
        条件2成立执行的代码
        ......

while循环练习

  • 打印星号(正方形)
1
2
3
4
5
6
7
8
9
10
11
12
# 重复打印5行星星
j = 0 
while j <= 4:
    # 一行星星的打印
    i = 0
    while i <= 4:
        # 一行内的星星不能换行,取消print默认结束符\n
        print('*', end='')
        i += 1
    # 每行结束要换行,这里借助一个空的print,利用print默认结束符换行
    print()
    j += 1

print默认结束符\n,可以设置end=' '修改默认行为

  • 99乘法表
1
2
3
4
5
6
7
8
j = 1
while j <= 9:
    i = 1
    while i <= j:
        print(f'{i}*{j}={i * j}',end='\t')
        i += 1
    print()
    j += 1

流程控制 for循环

for in 循环

1
2
3
4
5
6
7
8
9
for 临时变量 in 序列:
    重复执行的代码1
    重复执行的代码2
    ......
    
# for-in 循环如果需要计数,需要配合 range() 实现
# range 有两个参数,参数一是起始值 ,参数二是终止值
# 得到一个数字区间,是一个左闭右开区间, [start, end)
# 如果只给一个参数,那么默认是终止值 ,起始值默认是 0

循环 + else

1
2
3
4
5
循环可以和else配合使用,else下方缩进的代码指的是当循环正常结束之后要执行的代码。
while 条件:
    条件成立重复执行的代码
else:
    循环正常结束之后要执行的代码 # 如果上面的被break终止循环,则这行就不会执行了

image-20230927183645791

1
如果不用else,想要达到效果,就得自己写判断了

image-20230927183654014

字符串

遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
'''
字符串的遍历
遍历:依次取到字符串中的每一个字符
'''

s = 'Hello World'

# 遍历方式一 for-in
for c in s:
print(c, c.upper())

print('*' * 20)

# 遍历方式二 - for-in-range-配合下标

# len() 函数 是 length 的简写, 用来获取参数的长度(元素个数)
length = len(s)
for i in range(0, length):
c = s[i]
print(c, c.upper())


print('*' * 10)
# 遍历方式三 while-配合下标

i = 0
while i < length:
c = s[i]
print(c, c.upper())
i += 1

下标

从0开始

image-20230927183732190

切片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
序列[开始位置下标:结束位置下标:步长]
注意:
1. 不包含结束位置下标对应的数据, 正负整数均可;
2. 步长是选取间隔,正负整数均可,默认步长为1
name = "abcdefg"
print(name[2:5:1])  # cde
print(name[2:5])  # cde
print(name[:5])  # abcde
print(name[1:])  # bcdefg
print(name[:])  # abcdefg
print(name[::2])  # aceg
print(name[:-1])  # abcdef, 负1表示倒数第一个数据
print(name[-4:-1])  # def
print(name[::-1])  # gfedcba 字符串逆序

image-20230927183738286

查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
find():检测某个子串是否包含在这个字符串中,如果在返回这个子串开始的位置下标,不存在则返回-1。
字符串序列.find(子串, 开始位置下标, 结束位置下标):开始和结束位置下标可以省略,表示在整个字符串序列中查找。

mystr = "hello world and itcast and itheima and Python"
print(mystr.find('and'))  # 12
print(mystr.find('and', 15, 30))  # 23
print(mystr.find('ands'))  # -1

index():检测某个子串是否包含在这个字符串中,如果在返回这个子串开始的位置下标,不存在则报异常。
字符串序列.index(子串, 开始位置下标, 结束位置下标):开始和结束位置下标可以省略,表示在整个字符串序列中查找。

mystr = "hello world and itcast and itheima and Python"
print(mystr.index('and'))  # 12
print(mystr.index('and', 15, 30))  # 23
print(mystr.index('ands'))  # 报错

* rfind(): 和find()功能相同,但查找方向为右侧开始。
* rindex():和index()功能相同,但查找方向为右侧开始。
* count():返回某个子串在字符串中出现的次数

修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
replace():替换,有返回值,返回值是修改后的字符串,并不会修改原有的字符串
字符串序列.replace(旧子串, 新子串, 替换次数):替换次数如果查出子串出现次数,则替换次数为该子串出现次数

mystr = "hello world and itcast and itheima and Python"
print(mystr.replace('and', 'he')) # 结果:hello world he itcast he itheima he Python
print(mystr.replace('and', 'he', 1)) # 结果:hello world he itcast and itheima and Python
print(mystr) # 结果:hello world and itcast and itheima and Python

数据按照是否能直接修改分为可变类型和不可变类型两种。字符串类型的数据修改的时候不能改变原有字符串,属于不能直接修改数据的类型即是不可变类型。

# 分割
split():按照指定字符分割字符串,分割的字符会被去掉
splitlines(): 按行分割,对空白符\n处理
partition(): 按分割条件将字符串分割成三部分,分割条件前,分割条件,分割条件后
rpartition(): 从右分割
字符串序列.split(分割字符, num):num表示的是分割字符出现的次数,即将来返回数据个数为num+1个。

mystr = "hello world and itcast and itheima and Python"
print(mystr.split('and')) # 结果:['hello world ', ' itcast ', ' itheima ', ' Python']
print(mystr.split('and', 2)) # 结果:['hello world ', ' itcast ', ' itheima and Python']
print(mystr.split(' ')) # 结果:['hello', 'world', 'and', 'itcast', 'and', 'itheima', 'and', 'Python']
print(mystr.split(' ', 2)) # 结果:['hello', 'world', 'and itcast and itheima and Python']

join():用一个字符或子串合并字符串,即是将多个字符串合并为一个新的字符串
字符或子串.join(多字符串组成的序列)

list1 = ['chuan', 'zhi', 'bo', 'ke']
t1 = ('aa', 'b', 'cc', 'ddd')
print('_'.join(list1)) # 结果:chuan_zhi_bo_ke
print('...'.join(t1)) # 结果:aa...b...cc...ddd

大小写转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
capitalize():将字符串第一个字符转换成大写。

mystr = "hello world and itcast and itheima and Python"
# 结果:Hello world and itcast and itheima and python
print(mystr.capitalize())

capitalize()函数转换后,只字符串第一个字符大写,其他的字符全都小写。

title():将字符串每个单词首字母转换成大写。

mystr = "hello world and itcast and itheima and Python"
# 结果:Hello World And Itcast And Itheima And Python
print(mystr.title())

lower():将字符串中大写转小写。

mystr = "hello world and itcast and itheima and Python"
# 结果:hello world and itcast and itheima and python
print(mystr.lower())

upper():将字符串中小写转大写。

mystr = "hello world and itcast and itheima and Python"
# 结果:HELLO WORLD AND ITCAST AND ITHEIMA AND PYTHON
print(mystr.upper())

删除空白字符

1
2
3
lstrip():删除字符串左侧空白字符。
rstrip():删除字符串右侧空白字符。
strip():删除字符串两侧空白字符。

字符串对齐

1
2
3
4
ljust():返回一个原字符串左对齐,并使用指定字符(默认空格)填充至对应长度的新字符串
字符串序列.ljust(长度, 填充字符)
rjust():返回一个原字符串右对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串,语法和ljust()相同
center():返回一个原字符串居中对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串,语法和ljust()相同。

判断开头或结尾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
startswith():检查字符串是否是以指定子串开头,是则返回 True,否则返回 False。如果设置开始和结束位置下标,则在指定范围内检查。
字符串序列.startswith(子串, 开始位置下标, 结束位置下标)

mystr = "hello world and itcast and itheima and Python   "
print(mystr.startswith('hello')) # 结果:True
print(mystr.startswith('hello', 5, 20)) # 结果False

endswith():检查字符串是否是以指定子串结尾,是则返回 True,否则返回 False。如果设置开始和结束位置下标,则在指定范围内检查。
字符串序列.endswith(子串, 开始位置下标, 结束位置下标)

mystr = "hello world and itcast and itheima and Python"
print(mystr.endswith('Python')) # 结果:True
print(mystr.endswith('python')) # 结果:False
print(mystr.endswith('Python', 2, 20)) # 结果:False

isalpha():如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False

mystr1 = 'hello'
mystr2 = 'hello12345'
print(mystr1.isalpha()) # 结果:True
print(mystr2.isalpha()) # 结果:False

isdigit():如果字符串只包含数字则返回 True 否则返回 False

mystr1 = 'aaa12345'
mystr2 = '12345'
print(mystr1.isdigit()) # 结果: False
print(mystr2.isdigit()) # 结果:True

isalnum():如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False

mystr1 = 'aaa12345'
mystr2 = '12345-'
print(mystr1.isalnum()) # 结果:True
print(mystr2.isalnum()) # 结果:False

isspace():如果字符串中只包含空白,则返回 True,否则返回 False

mystr1 = '1 2 3 4 5'
mystr2 = '     '
print(mystr1.isspace()) # 结果:False
print(mystr2.isspace()) # 结果:True

特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 一对引号字符串
name1 = 'Tom'
name2 = "Rose"
# 三引号字符串
name3 = ''' Tom '''
name4 = """ Rose """
a = ''' i am Tom,
        nice to meet you! '''

b = """ i am Rose,
        nice to meet you! """
注意:三引号形式的字符串支持换行。
思考:如果创建一个字符串I'm Tom?
c = "I'm Tom"
d = 'I\'m Tom'

输出

1
2
3
4
5
print('hello world')

name = 'Tom'
print('我的名字是%s' % name)
print(f'我的名字是{name}')

输入

1
2
3
4
5
6
7
8
9
在Python中,使用input()接收用户输入。

name = input('请输入您的名字:')
print(f'您输入的名字是{name}')
print(type(name))

password = input('请输入您的密码:')
print(f'您输入的密码是{password}')
print(type(password))

列表、元组、字典、集合、公共操作、推导式

05_列表、元组、字典、集合、公共操作、推导式

列表

1
2
[数据1, 数据2, 数据3, 数据4......]
ps:可以一次性存储多个数据,且可以为不同数据类型。但是最好是相同数据类型,比较号操作

查找

下标

1
2
3
4
name_list = ['Tom', 'Lily', 'Rose']
print(name_list[0])  # Tom
print(name_list[1])  # Lily
print(name_list[2])  # Rose

函数

  • index():返回指定数据所在位置的下标,
1
2
name_list = ['Tom', 'Lily', 'Rose']
print(name_list.index('Lily', 0, 2))  # 1
  • count():统计指定数据在当前列表中出现的次数。
1
2
name_list = ['Tom', 'Lily', 'Rose']
print(name_list.count('Lily'))  # 1
  • len():访问列表长度,即列表中数据的个数。
1
2
name_list = ['Tom', 'Lily', 'Rose']
print(len(name_list))  # 3 

判断是否存在

  • in:判断指定数据在某个列表序列,如果在返回True,否则返回False
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
print('Lily' in name_list) # 结果:True
print('Lilys' in name_list) # 结果:False
  • not in:判断指定数据不在某个列表序列,如果不在返回True,否则返回False
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
print('Lily' not in name_list)# 结果:False
print('Lilys' not in name_list)# 结果:True 

增加

  • append():列表结尾追加数据。
1
2
3
4
5
6
7
8
9
name_list = ['Tom', 'Lily', 'Rose']
name_list.append('xiaoming')
print(name_list) # 结果:['Tom', 'Lily', 'Rose', 'xiaoming']
ps:列表追加数据的时候,直接在原列表里面追加了指定数据,即修改了原列表,故列表为可变类型数据。

如果append()追加的数据是一个序列,则追加整个序列到列表
name_list = ['Tom', 'Lily', 'Rose']
name_list.append(['xiaoming', 'xiaohong'])
print(name_list) # 结果:['Tom', 'Lily', 'Rose', ['xiaoming', 'xiaohong']]
  • extend():列表结尾追加数据,如果数据是一个序列,则将这个序列的数据逐一添加到列表
1
2
3
4
5
6
7
name_list = ['Tom', 'Lily', 'Rose']
name_list.extend('xiaoming')
print(name_list) # 结果:['Tom', 'Lily', 'Rose', 'x', 'i', 'a', 'o', 'm', 'i', 'n', 'g']

name_list = ['Tom', 'Lily', 'Rose']
name_list.extend(['xiaoming', 'xiaohong'])
print(name_list) # 结果:['Tom', 'Lily', 'Rose', 'xiaoming', 'xiaohong']
  • insert():指定位置新增数据。
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
name_list.insert(1, 'xiaoming')
print(name_list) # 结果:['Tom', 'xiaoming', 'Lily', 'Rose']  

删除

  • del
1
2
3
4
5
6
7
name_list = ['Tom', 'Lily', 'Rose']
del name_list
print(name_list) # 结果:报错提示:name 'name_list' is not defined

name_list = ['Tom', 'Lily', 'Rose']
del name_list[0]
print(name_list) # 结果:['Lily', 'Rose']
  • pop():删除指定下标的数据(默认为最后一个),并返回该数据。
1
2
3
4
name_list = ['Tom', 'Lily', 'Rose']
del_name = name_list.pop(1)
print(del_name) # 结果:Lily
print(name_list) # 结果:['Tom', 'Rose']
  • remove():移除列表中某个数据的第一个匹配项。
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
name_list.remove('Rose') 
print(name_list) # 结果:['Tom', 'Lily']
  • clear():清空列表
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
name_list.clear()
print(name_list) # 结果: []

修改

  • 修改指定下标数据
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
name_list[0] = 'aaa'
print(name_list) # 结果:['aaa', 'Lily', 'Rose']
  • 逆置:reverse()
1
2
3
num_list = [1, 5, 2, 3, 6, 8]
num_list.reverse()
print(num_list) # 结果:[8, 6, 3, 2, 5, 1]
  • 排序:sort()
1
2
3
4
5
6
列表序列.sort( key=None, reverse=False)
注意:reverse表示排序规则,reverse = True 降序, reverse = False 升序(默认)

num_list = [1, 5, 2, 3, 6, 8]
num_list.sort()
print(num_list) # 结果:[1, 2, 3, 5, 6, 8] 

复制

  • 函数:copy()
1
2
3
pythonname_list = ['Tom', 'Lily', 'Rose']
name_li2 = name_list.copy()
print(name_li2) # 结果:['Tom', 'Lily', 'Rose'] 

循环遍历

  • while
1
2
3
4
5
name_list = ['Tom', 'Lily', 'Rose']
i = 0
while i < len(name_list):
    print(name_list[i])
    i += 1
  • for
1
2
3
name_list = ['Tom', 'Lily', 'Rose']
for i in name_list:
    print(i) 

嵌套

1
2
3
4
name_list = [['小明', '小红', '小绿'], ['Tom', 'Lily', 'Rose'], ['张三', '李四', '王五']]
# 查找到数据"李四"
print(name_list[2]) # 第一步:按下标查找到李四所在的列表
print(name_list[2][1]) # 第二步:从李四所在的列表里面,再按下标找到数据李四

元组

1
2
3
4
5
6
7
8
9
10
11
12
13
使用小括号,且逗号隔开各个数据,数据可以是不同的数据类型。

t1 = (10, 20, 30# 多个数据元组
t2 = (10,) # 单个数据元组
print(type(t2))  # tuple

t3 = (20)
print(type(t3))  # int
t4 = ('hello')
print(type(t4))  # str
ps:注意:如果定义的元组只有一个数据,那么这个数据后面也好添加逗号,否则数据类型为唯一的这个数据的数据类型

元组数据不支持修改,只支持查找
  • 按下标查找数据
1
2
tuple1 = ('aa', 'bb', 'cc', 'bb')
print(tuple1[0])  # aa
  • index():查找某个数据,如果数据存在返回对应的下标,否则报错,语法和列表、字符串的index方法相同。
1
2
tuple1 = ('aa', 'bb', 'cc', 'bb')
print(tuple1.index('aa'))  # 0
  • count():统计某个数据在当前元组出现的次数。
1
2
tuple1 = ('aa', 'bb', 'cc', 'bb')
print(tuple1.count('bb'))  # 2
  • len():统计元组中数据的个数
1
2
3
4
5
6
7
8
tuple1 = ('aa', 'bb', 'cc', 'bb')
print(len(tuple1))  # 4
ps:元组内的直接数据如果修改则立即报错,但是如果元组里面有列表,修改列表里面的数据则是支持的,故自觉很重要(尽可能不修改)。

tuple2 = (10, 20, ['aa', 'bb', 'cc'], 50, 30)
print(tuple2[2])  # 访问到列表
tuple2[2][0] = 'aaaaa' # 结果:(10, 20, ['aaaaa', 'bb', 'cc'], 50, 30)
print(tuple2)

嵌套元组的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
# 定义一个嵌套元组
t = (1,2,3,(4,5,6),(7,8,9))

# 遍历
for v in t:
# isinstance() 判断参数一是否是参数二的类型对象
# 通过 isinstance 判断 遍历的元素是否是一个元组,
# 如果是就继续遍历,不是直接 输出
if isinstance(v,tuple):
for v2 in v:
print(v2)
else:
print(v)

字典

1
2
3
4
5
6
7
8
字典为可变类型。

# 有数据字典
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}

# 空字典
dict2 = {}
dict3 = dict()

增/改

1
2
3
4
5
6
7
8
字典序列[key] = 值
如果key存在则修改这个key对应的值;如果key不存在则新增此键值对。

dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
dict1['name'] = 'Rose'
print(dict1) # 结果:{'name': 'Rose', 'age': 20, 'gender': '男'}
dict1['id'] = 110
print(dict1) # {'name': 'Rose', 'age': 20, 'gender': '男', 'id': 110}

  • del() / del:删除字典或删除字典中指定键值对。
1
2
3
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
del dict1['gender']
print(dict1) # 结果:{'name': 'Tom', 'age': 20}
  • clear():清空字典
1
2
3
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
dict1.clear()
print(dict1)  # {} 

  • key值查找
1
2
3
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1['name'])  # Tom
print(dict1['id'])  # 报错 :如果当前查找的key存在,则返回对应的值;否则则报错。
* get():如果当前查找的key不存在则返回第二个参数\(默认值\),如果省略第二个参数,则返回None。
1
2
3
4
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.get('name'))  # Tom
print(dict1.get('id', 110))  # 110
print(dict1.get('id'))  # None
  • keys()
1
2
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.keys())  # dict_keys(['name', 'age', 'gender'])
  • values()
1
2
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.values())  # dict_values(['Tom', 20, '男'])
  • items()
1
2
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
print(dict1.items())  # dict_items([('name', 'Tom'), ('age', 20), ('gender', '男')])

循环遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 遍历字典的key
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
for key in dict1.keys():
    print(key)
# 遍历字典的value
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
for value in dict1.values():
    print(value)
# 遍历字典的元素
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
for item in dict1.items():
    print(item)
# 遍历字典的键值对
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
for key, value in dict1.items():
    print(f'{key} = {value}')

集合

1
2
3
4
5
6
7
8
9
10
11
12
13
创建集合使用{}或set(), 但是如果要创建空集合只能使用set(),因为{}用来创建空字典。
s1 = {10, 20, 30, 40, 50}
print(s1)
s2 = {10, 30, 20, 10, 30, 40, 30, 50}
print(s2)
s3 = set('abcdefg')
print(s3) # {'d','e','f','g','a','b','c'}
s4 = set()
print(type(s4))  # set
s5 = {}
print(type(s5))  # dict
1. 集合可以去掉重复数据;
2. 集合数据是无序的,故不支持下标  

增加

  • add()
1
2
3
4
s1 = {10, 20}
s1.add(100)
s1.add(10)
print(s1)  # {100, 10, 20}
  • update():追加的数据是序列。
1
2
3
4
5
s1 = {10, 20}
# s1.update(100)  # 追加单一元素会报错
s1.update([100, 200])
s1.update('abc')
print(s1) 

删除

  • remove(),删除集合中的指定数据,如果数据不存在则报错。
1
2
3
4
5
s1 = {10, 20}
s1.remove(10)
print(s1)
s1.remove(10)  # 报错
print(s1) 
  • discard(),删除集合中的指定数据,如果数据不存在也不会报错。
1
2
3
4
5
s1 = {10, 20}
s1.discard(10)
print(s1)
s1.discard(10)
print(s1)
  • pop(),随机删除集合中的某个数据,并返回这个数据。
1
2
3
4
s1 = {10, 20, 30, 40, 50}
del_num = s1.pop()
print(del_num)
print(s1) 

查找

  • in:判断数据在集合序列
  • not in:判断数据不在集合序列
1
2
3
s1 = {10, 20, 30, 40, 50}
print(10 in s1) # True
print(10 not in s1) # False

公共操作

运算符

image-20230927183816867

  • +:合并
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 字符串
str1 = 'aa'
str2 = 'bb'
str3 = str1 + str2
print(str3)  # aabb

# 2. 列表
list1 = [1, 2]
list2 = [10, 20]
list3 = list1 + list2
print(list3)  # [1, 2, 10, 20]

# 3. 元组
t1 = (1, 2)
t2 = (10, 20)
t3 = t1 + t2
print(t3)  # (10, 20, 100, 200)
  • *:复制
1
2
3
4
5
6
7
8
9
10
# 1. 字符串
print('-' * 10)  # ----------

# 2. 列表
list1 = ['hello']
print(list1 * 4)  # ['hello', 'hello', 'hello', 'hello']

# 3. 元组
t1 = ('world',)
print(t1 * 4)  # ('world', 'world', 'world', 'world')
  • in/not in
1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 字符串
print('a' in 'abcd')  # True
print('a' not in 'abcd')  # False

# 2. 列表
list1 = ['a', 'b', 'c', 'd']
print('a' in list1)  # True
print('a' not in list1)  # False

# 3. 元组
t1 = ('a', 'b', 'c', 'd')
print('aa' in t1)  # False
print('aa' not in t1)  # True

公共方法

image-20230927183825250

  • len()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 字符串
str1 = 'abcdefg'
print(len(str1))  # 7
# 2. 列表
list1 = [10, 20, 30, 40]
print(len(list1))  # 4
# 3. 元组
t1 = (10, 20, 30, 40, 50)
print(len(t1))  # 5
# 4. 集合
s1 = {10, 20, 30}
print(len(s1))  # 3
# 5. 字典
dict1 = {'name': 'Rose', 'age': 18}
print(len(dict1))  # 2
  • del()
1
2
3
4
5
6
7
8
# 1. 字符串
str1 = 'abcdefg'
del str1
print(str1) # not defined
# 2. 列表
list1 = [10, 20, 30, 40]
del(list1[0])
print(list1)  # [20, 30, 40]
  • max()
1
2
3
4
5
6
# 1. 字符串
str1 = 'abcdefg'
print(max(str1))  # g
# 2. 列表
list1 = [10, 20, 30, 40]
print(max(list1))  # 40
  • min()
1
2
3
4
5
6
# 1. 字符串
str1 = 'abcdefg'
print(min(str1))  # a
# 2. 列表
list1 = [10, 20, 30, 40]
print(min(list1))  # 10
  • range()
1
2
3
4
5
6
7
8
9
10
# 1 2 3 4 5 6 7 8 9
for i in range(1, 10, 1): # 1...9
    print(i)
# 1 3 5 7 9
for i in range(1, 10, 2): # 2是步骤,此处生成奇数
    print(i)
# 0 1 2 3 4 5 6 7 8 9
for i in range(10): # 从0开始
    print(i)
ps:注意:range()生成的序列不包含end数字
  • enumerate()
1
2
3
4
5
6
7
8
enumerate(可遍历对象, start=0)
start参数用来设置遍历数据的下标的起始值,默认为0

list1 = ['a', 'b', 'c', 'd', 'e']
for i in enumerate(list1):
    print(i)
for index, char in enumerate(list1, start=1):  # start=1 下标起始值从1开始
    print(f'下标是{index}, 对应的字符是{char}'

容器类型转换

  • tuple() 将某个序列转换成元组
1
2
3
4
list1 = [10, 20, 30, 40, 50, 20]
s1 = {100, 200, 300, 400, 500}
print(tuple(list1))
print(tuple(s1))
  • list():将某个序列转换成列表
1
2
3
4
t1 = ('a', 'b', 'c', 'd', 'e')
s1 = {100, 200, 300, 400, 500}
print(list(t1))
print(list(s1))
  • set():将某个序列转换成集合
1
2
3
4
list1 = [10, 20, 30, 40, 50, 20]
t1 = ('a', 'b', 'c', 'd', 'e')
print(set(list1))
print(set(t1))

推导式

列表推导式

1
用一个表达式创建一个有规律的列表或控制一个有规律列表。列表推导式又叫列表生成式。
  • 为什么用?=>方便
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
##### 创建一个0-10的列表。######
-------- while循环实现 --------
# 1. 准备一个空列表
list1 = []
# 2. 书写循环,依次追加数字到空列表list1中
i = 0
while i < 10:
    list1.append(i)
    i += 1
print(list1)
-------- for循环实现 --------
list1 = []
for i in range(10):
    list1.append(i)
print(list1)
-------- 列表推导式实现 --------
# 列表变量 = [表达式 for 变量 in range(10)] # 表达式需要使用后面的变量
list1 = [i for i in range(10)]
print(list1) 
  • 带if的列表推导式
1
2
3
4
5
6
7
###### 创建0-10的偶数列表 ######
方法一:range()步长实现
list1 = [i for i in range(0, 10, 2)]
print(list1)
方法二:if实现
list1 = [i for i in range(10) if i % 2 == 0]
print(list1)
  • 多个for循环实现列表推导式
1
2
3
生成:[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
list1 = [(i, j) for i in range(1, 3) for j in range(3)]
print(list1) 

字典推导式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'man']
如何快速合并为一个字典? => 字典推导式作用:快速合并列表为字典或提取字典中目标数据。

# 1. 创建一个字典:字典key是1-5数字,value是这个数字的2次方。
dict1 = {i: i**2 for i in range(1, 5)}
print(dict1)  # {1: 1, 2: 4, 3: 9, 4: 16}

# 2. 将两个列表合并为一个字典
list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'man']
dict1 = {list1[i]: list2[i] for i in range(len(list1))}
print(dict1)

# 3.   提取字典中目标数据
counts = {'MBP': 268, 'HP': 125, 'DELL': 201, 'Lenovo': 199, 'acer': 99}
# 需求:提取上述电脑数量大于等于200的字典数据
count1 = {key: value for key, value in counts.items() if value >= 200}
print(count1)  # {'MBP': 268, 'DELL': 201} 

集合推导式

1
2
3
4
5
6
# 创建一个集合,数据为下方列表的2次方。 list1 = [1, 1, 2]

list1 = [1, 1, 2]
set1 = {i ** 2 for i in list1}
print(set1)  # {1, 4}
ps: 集合有数据去重功能。

函数

函数就是将一段具有独立功能的代码块整合到一个整体并命名,在需要的位置调用这个名称即可完成对应的需求。
函数在开发过程中,可以更高效的实现代码重用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def 函数名(参数): # 形参
    代码1
    代码2
    ......
函数名(参数) # 实参
1. 不同的需求,参数可有可无。
2. 在Python中,函数必须==先定义后使用==。

# 函数可以有返回值,返回值也可以作为其他函数的参数
def sum_num(a, b):
    return a + b # return 下面的代码不执行
result = sum_num(1, 2# 用result变量保存函数返回值
print(result)
# 返回多个值
def return_num():
    return 1, 2
result = return_num()
print(result)  # (1, 2) 返回多个数据的时候,默认是元组类型。可以连接列表、元组或字典,以返回多个值。

# 函数文档
def 函数名(参数):
    """ 说明文档的位置 """
    代码
    ......
help(函数名) # 查看函数说明文档 

# 暂时跳过
def testa():
    pass # 如果暂时不知道函数体怎么写,可以先pass,避免语法报错

没有return返回值,默认返回是None

变量作用域

定义在函数内部的变量是局部变量(在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。)
外部是全局变量(所谓全局变量,指的是在函数体内、外都能生效的变量。多个函数都要使用的变量可以定义为全局变量)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def testA():
    a = 100
    print(a)
testA()  # 100
print(a)  # 报错:name 'a' is not defined 变量a是定义在testA函数内部的变量,在函数外部访问则立即报错

### 如何在函数体内部修改全局变量 ### 
a = 100

def testA():
    print(a)

def testB():
    # global 关键字声明a是全局变量
    global a
    a = 200
    print(a)

testA()  # 100
testB()  # 200
print(f'全局变量a = {a}')  # 全局变量a = 200 

# 变量查找规则
# LEGB
# Local -> EnClosed -> Global -> Buildins
# 本地 -> 闭包 -> 全局 -> 内建

函数的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 位置参数:调用函数时根据函数定义的参数位置来传递参数。
def user_info(name, age, gender):
    print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')
user_info('TOM', 20, '男') # 注意:传递和定义参数的顺序及个数必须一致。

# 关键字参数:函数调用,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
def user_info(name, age, gender):
    print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')
user_info('Rose', age=20, gender='女')
user_info('小明', gender='男', age=16)
ps : 注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。

#  缺省参数: 默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
def user_info(name, age, gender='男'):
    print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}')
user_info('TOM', 20) # 注意:函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值。
user_info('Rose', 18, '女'

#  不定长参数 :  可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便
- 包裹位置传递
def user_info(*args):
    print(args)
user_info('TOM'# ('TOM',)
user_info('TOM', 18# ('TOM', 18)
ps: 传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。
- 包裹关键字传递
def user_info(**kwargs):
    print(kwargs)
user_info(name='TOM', age=18, id=110# {'name': 'TOM', 'age': 18, 'id': 110}
综上:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程 

拆包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
拆包:元组
def return_num():
    return 100, 200
num1, num2 = return_num()
print(num1)  # 100
print(num2)  # 200

拆包:字典
dict1 = {'name': 'TOM', 'age': 18}
a, b = dict1
# 对字典进行拆包,取出来的是字典的key
print(a)  # name
print(b)  # age
print(dict1[a])  # TOM
print(dict1[b])  # 18

组包

1
2
3
4
5
# 组包

a = 1,2,3,4,5
print(a) # (1, 2, 3, 4, 5)
print(type(a)) # <class 'tuple'>

交换变量值

1
2
3
4
5
6
借助第三变量存储数据。
python中有更方便的交换:
a, b = 1, 2
a, b = b, a
print(a)  # 2
print(b)  # 1

引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
在python中,值是靠引用来传递来的。
我们可以用id()来判断两个变量是否为同一个值的引用。 id值可以理解为那块内存的地址标识。
# 1. int类型
a = 1
b = a
print(b)  # 1

print(id(a))  # 140708464157520
print(id(b))  # 140708464157520

a = 2
print(b)  # 1,说明int类型为不可变类型

print(id(a))  # 140708464157552,此时得到是的数据2的内存地址
print(id(b))  # 140708464157520

# 2. 列表
aa = [10, 20]
bb = aa

print(id(aa))  # 2325297783432
print(id(bb))  # 2325297783432

aa.append(30)
print(bb)  # [10, 20, 30], 列表为可变类型 
print(id(aa))  # 2325297783432
print(id(bb))  # 2325297783432

可变和不可变类型

所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变.

  • 可变类型
    • 列表
    • 字典
    • 集合
  • 不可变类型
    • 整型
    • 浮点型
    • 字符串
    • 元组

不可变的要修改要用global声明一下

递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
递归是一种编程思想
1. 在我们日常开发中,如果要遍历一个文件夹下面所有的文件,通常会使用递归来实现;
2. 在后续的算法课程中,很多算法都离不开递归,例如:快速排序。
# 3 + 2 + 1
def sum_numbers(num):
    # 1.如果是1,直接返回1 -- 出口
    if num == 1: # 必须有出口
        return 1
    # 2.如果不是1,重复执行累加并返回结果
    return num + sum_numbers(num-1) #  函数内部自己调用自己

sum_result = sum_numbers(3)
# 输出结果为6
print(sum_result)

image-20230927183853219

lambda

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda简化。
lambda 参数列表 : 表达式 
* lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用。
* lambda表达式能接收任何数量的参数但只能返回一个表达式的值。

# 函数
def fn1():
    return 200
print(fn1) # 函数fn1的地址
print(fn1())

# lambda表达式
fn2 = lambda: 100
print(fn2) # 注意:直接打印lambda表达式,输出的是此lambda的内存地址
print(fn2())

# 计算a + b
def add(a, b):
    return a + b
result = add(1, 2)
print(result)
# lambda简化
fn1 = lambda a, b: a + b
print(fn1(1, 2))

# lambda 参数
## 无参数
fn1 = lambda: 100
print(fn1())
## 一个参数
fn1 = lambda a: a
print(fn1('hello world'))
## 默认参数
fn1 = lambda a, b, c=100: a + b + c
print(fn1(10, 20))
## 可变参数:*args
fn1 = lambda *args: args
print(fn1(10, 20, 30))
注意:这里的可变参数传入到lambda之后,返回值为元组。
## 可变参数:**kwargs
fn1 = lambda **kwargs: kwargs
print(fn1(name='python', age=20))

# 带判断的lambda
fn1 = lambda a, b: a if a > b else b
print(fn1(1000, 500))

# 列表数据按字典key的值排序
students = [
    {'name': 'TOM', 'age': 20},
    {'name': 'ROSE', 'age': 19},
    {'name': 'Jack', 'age': 22}
]
# 默认sort方法是不能对字典进行比较排序的 ,TypeError: '<' not supported between instances of 'dict' and 'dict'
# 按name值升序排列
students.sort(key=lambda x: x['name'])
print(students)
# 按name值降序排列
students.sort(key=lambda x: x['name'], reverse=True)
print(students)
# 按age值升序排列
students.sort(key=lambda x: x['age'])
print(students)

高阶函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
把函数作为参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式。

abs()函数可以完成对数字求绝对值计算。
abs(-10)  # 10

round()函数可以完成对数字的四舍五入计算。
round(1.2)  # 1
round(1.9)  # 2

# 任意两个数字,按照指定要求整理数字后再进行求和计算。
-------- 方法1 ----------
def add_num(a, b):
    return abs(a) + abs(b)
result = add_num(-1, 2)
print(result)  # 3
-------- 方法2 ----------
def sum_num(a, b, f):
    return f(a) + f(b)
result = sum_num(-1, 2, abs)
print(result)  # 3
两种方法对比之后,发现,方法2的代码会更加简洁,函数灵活性更高。
函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度较快。

### 内置高阶函数 ### 
# map()
map(func, lst):将传入的函数变量func作用到lst变量的每个元素中,并将结果组成新的列表(Python2)/迭代器(Python3)返回。
# 需求:计算list1序列中各个数字的2次方。
list1 = [1, 2, 3, 4, 5]
def func(x):
    return x ** 2
result = map(func, list1)
可以用lambda写:map(lambda x:x**2,list1)

print(result)  # <map object at 0x0000013769653198>
print(list(result))  # [1, 4, 9, 16, 25]

map实现原理:

image-20221020075316780

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# reduce()
reduce(func,lst),其中func必须有两个参数。每次func计算的结果继续和序列的下一个元素做累积计算。
注意:reduce()传入的参数func必须接收2个参数。
# 需求:计算list1序列中各个数字的累加和。
import functools
list1 = [1, 2, 3, 4, 5]
def func(a, b):
    return a + b

result = functools.reduce(func, list1)
print(result)  # 15

# filter()
filter(func, lst)函数用于过滤序列, 过滤掉不符合条件的元素, 返回一个 filter 对象。如果要转换为列表, 可以使用 list() 来转换。
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def func(x):
    return x % 2 == 0
result = filter(func, list1)

print(result)  # <filter object at 0x0000017AF9DC3198>
print(list(result))  # [2, 4, 6, 8, 10]

文件操作

基础操作:打开、关闭、读、写、复制….

1
2
3
#### 打开 open(name, mode) ####
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。

image-20230927183911023

rt模式下,python在读取文本时会自动把\r\n转换成\n.

wt模式下,Python写文件时会用\r\n来表示换行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
f = open('test.txt', 'w') # 此时的f是open函数的文件对象

####  写 : 对象对象.write('内容') ####
f = open('test.txt', 'w') # 1. 打开文件
f.write('hello world') # 2.文件写入
f.close() # 3. 关闭文件
1. w和a模式:如果文件不存在则创建该文件;如果文件存在,w模式先清空再写入,a模式直接末尾追加。
2. r模式:如果文件不存在则报错。只读,该模式下无法写入

#### 读 :文件对象.read(num) ####
num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。
readlines():可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
f = open('test.txt')
content = f.readlines()、
print(content) # ['hello world\n', 'abcdefg\n', 'aaa\n', 'bbb\n', 'ccc']
f.close() #关闭文件:

readline():readline()一次读取一行内容。
f = open('test.txt')
content = f.readline()
print(f'第一行:{content}')
content = f.readline()
print(f'第二行:{content}')
f.close() # 关闭文件

seek():用来移动文件指针。文件对象.seek(偏移量, 起始位置)
起始位置:
* 0:文件开头
* 1:当前位置
* 2:文件结尾

#### 文件对象.close() ####

文件备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
需求:用户输入当前目录下任意文件名,程序完成对该文件的备份功能(备份文件名为xx[备份]后缀,例如:test[备份].txt)。
1.接收用户输入目标文件名
old_name = input('请输入您要备份的文件名:')
# 2.1 提取文件后缀点的下标
index = old_name.rfind('.') 
# print(index)  # 后缀中.的下标
# print(old_name[:index])  # 源文件名(无后缀)
# 2.2 组织新文件名 旧文件名 + [备份] + 后缀
new_name = old_name[:index] + '[备份]' + old_name[index:]
# 打印新文件名(带后缀)
# print(new_name)
# 3.1 打开文件
old_f = open(old_name, 'rb')
new_f = open(new_name, 'wb')
# 3.2 将源文件数据写入备份文件
while True:
    con = old_f.read(1024)
    if len(con) == 0:
        break
    new_f.write(con)
# 3.3 关闭文件
old_f.close()
new_f.close()

文件、文件夹操作

1
2
3
4
5
6
7
8
9
10
import os
os.函数名()

# 文件重命名:os.rename(目标文件名, 新文件名)
# 删除文件:os.remove(目标文件名)
# 创建文件夹:os.mkdir(文件夹名字)
# 删除文件夹:os.rmdir(文件夹名字)
# 获取当前目录:os.getcwd()
# 改变默认目录:os.chdir(目录) # 默认当前目录,这个相当于切换后续命令的工作目录
# 获取目录列表: os.listdir(目录)

with语句的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
----------------- 写文件 -----------
# 1、以写的方式打开文件
f = open("1.txt", "w")
# 2、写入文件内容
f.write("hello world")
# 3、关闭文件
f.close()

    文件使用完后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的

上面的代码有可能'w',写成'r'
    由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。
    为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来解决

----------------- 安全写法 ---------------- 
try:
    # 1、以读的方式打开文件
    f = open("1.txt", "r")
    # 2、读取文件内容
    f.write("xxxxx")

except IOError as e:
    print("文件操作出错", e)

finally:
    # 3、关闭文件
    f.close()

    这种方法虽然代码运行良好,但是缺点就是代码过于冗长,并且需要添加try-except-finally语句,不是很方便,也容易忘记.

    在这种情况下,Python提供了 with 语句的这种写法,既简单又安全,并且 with 语句执行完成以后自动调用关闭文件操作,即使出现异常也会自动调用关闭文件操作。

----------- 简单&安全写法 ---------------
# 1、以写的方式打开文件
with open("1.txt", "w") as f:
# 2、读取文件内容
f.write("hello world")
  • 为什么with管理器可以达到这种效果?

上下文管理器

1
2
3
4
5
    一个类只要实现了__enter__()和__exit__()这个两个方法,通过该类创建的对象我们就称之为上下文管理器。

    __enter__表示上文方法,需要返回一个操作文件对象
    __exit__表示下文方法,with语句执行完成会自动执行,即使出现异常也会执行该方法。
    上下文管理器可以使用 with 语句,with语句之所以这么强大,背后是由上下文管理器做支撑的,也就是说刚才使用 open 函数创建的文件对象就是就是一个上下文管理器对象。

模拟with open:

image-20230927183927005

  • 上下文管理器的另外一种实现方式
1
    假如想要让一个函数成为上下文管理器,Python 还提供了一个 @contextmanager 的装饰器,更进一步简化了上下文管理器的实现方式。通过 yield 将函数分割成两部分,yield 上面的语句在 __enter__ 方法中执行,yield 下面的语句在 __exit__ 方法中执行,紧跟在 yield 后面的参数是函数的返回值。

image-20230927183936083

1
with只能和上下文管理器一起用