Python 学习笔记:基础篇

1. 安装 Python

点击下载 Python 3.13.9

安装时勾选 Use admin privileges when installing py.exeAdd python.exe to PATH

请自行下载并安装 PyCharm

2. 配置 Python 镜像源

打开 CMD,在其中执行以下命令:

bash 复制代码
# 升级 PIP
python -m pip install -i https://mirrors.huaweicloud.com/repository/pypi/simple --upgrade pip

# 生成 pip.ini 配置文件
pip config set global.index-url https://mirrors.huaweicloud.com/repository/pypi/simple

# 编辑 pip.ini 配置文件
[global]
index-url = https://mirrors.huaweicloud.com/repository/pypi/simple
trusted-host = mirrors.huaweicloud.com
timeout = 120

测试项目:获取硬件规格

  1. 在 PyCharm 中创建一个 python 项目
  2. 使用 PyCharm 终端安装 psutil 工具
bash 复制代码
# 安装
pip install psutil

# 验证安装
pip list
Package Version
------- -------
pip     25.1.1
psutil  7.1.1   # <- HERE
  1. 在项目中新建一个 .py 文件,在其中添加以下代码
py 复制代码
import psutil

print(psutil.cpu_count(logical=False))  # 获取 CPU 物理核心数
print(psutil.cpu_count())               # 获取 CPU 逻辑核心数
  1. 执行文件,即可看到结果
bash 复制代码
14
28

3. Python 基础

3.1 Python 语法规则

Python 不同于常见的 C 或 Java 语言,其语末没有 ; 标记,且不使用 {} 标记代码块,使用类似 yaml 语法的缩进进行标记代码所属

示例:

py 复制代码
for i in range(5):
    print(i)                # 属于 for 循环
    print("Hello,world!")   # 属于 for 循环
print("End") # 不属于 for 循环

3.2 注释

Python 使用 # 标记单行注释,使用 '''""" 标记多行注释,语法如下:

py 复制代码
# 单行注释

'''
多行注释
'''

"""
多行注释
"""

!TIP

在 PyCharm 中,可以选中需要注释的代码范围,按下 Ctrl + / 进行快速注释

3.3 输出函数

3.4 标识符与关键字

Python 的标识符命名规则如下:

  1. 标示符可以由字母下划线数字组成
  2. 标识符不能以数字开头
  3. Python 中的标识符严格区分大小写,如 tomTom 是不同的标识符
  4. Python 中的标识符不能使用关键字

使用以下代码可以查看关键字列表

py 复制代码
import keyword
print(keyword.kwlist)

Python 的标识符命名规范如下:

  1. 见名知意,如(姓名:name;年龄:age)
  2. 常量名使用大写的单个单词或由下画线连接的多个单词(ORDER_LIST_LIMIT)。
  3. 模块名、函数名使用小写的单个单词或由下画线连接的多个单词(low_with_under)。
  4. 类名使用大写字母开头的单个或多个单词。(Cat,Dog,Person)

3.5 变量

Python 变量不需要在定义时为其指定数据类型

py 复制代码
num = 10
print(num)

3.6 数据类型

Python 数据类型大致可分为以下几类:

  • 数值
  • 字符串
  • 组合数据

3.6.1 数值

数值包括以下具体数据类型

数据类型 示例
整型(int) 10-10True(1)False(0)
浮点型(float) 3.14-2.70.02.0
复数(complex) 2x+3

整型类型用于表示整数,在计算机中,整型常用的计数方式有4种

  • 二进制:以 0b0B 开头,使用 bin() 进行类型转换
  • 八进制:以 0o0O 开头,使用 oct() 进行类型转换
  • 十进制:使用 int() 进行类型转换
  • 十六进制:以 0x0X 开头,使用 hex() 进行类型转换

在 Python 中,浮点类型属于特殊的整形,其 True 值为 1False 值为 0

3.6.2 组合数据

组合数据又分为以下三类

  • 组合数据
    • 序列
    • 集合(set)
    • 映射(dict)

序列包含一下数据类型

数据类型 说明 示例
列表(list) 使用 [] 标记,可以存放任意数量、任意类型的元素,可以被修改 [1, 2, 'hello']
元组(tuple) 使用 () 标记,可以存放任意数量、任意类型的元素,不可被修改 (1, 2, 'hello')

集合类型与列表和元素类似,可以存放任意数量、任意类型的元素,区别是,集合类型中的数据无序且唯一,使用 {} 标记

映射类型又名字典类型,使用 键(key):值(value) 的键值对方式存储数据,键不能重复,使用 {} 创建键值对

3.6.3 数据类型转换

使用 (数据类型)变量名 可以对变量的数据类型进行转换

数据类型中文名 数据类型英文名
整形 int
浮点型 float
字符串 str
列表 list
元组 tuple
集合 set
字典 dict
复数 complex

3.7 变量的输入和输出

变量的输入使用 input() 函数,变量的输出使用 print() 函数

示例:

py 复制代码
num = input("Input a number: ")
print(num)

运行效果如下:

bash 复制代码
Input a number: # 100
100

3.7.1 输入函数 input()

输入函数默认的输入数据类型为 str

语法如下:

py 复制代码
变量=input([提示字符串])

示例:

py 复制代码
age = input("Please input your age: ")

3.7.2 输出函数 print()

print() 函数语法如下:

py 复制代码
print([输出文本][, sep=分隔符][, end=结尾符][, file=输出文件对象])

# 输出文本:字面意思
# 分隔符:设置多个内容之间使用指定字符进行分割,默认为空格
# 结尾符:设置输出结尾符号,默认为回车 \n

示例:

py 复制代码
for i in range(10):
    print(i, end='')

print()

for i in range(10):
    print(i, end=' ')

示例 2:九九乘法表

py 复制代码
for i in range(1,10):
    for j in range(1,i+1):
        print(f'{j}x{i}={i*j}',end='\t')
    print()

3.8 运算符

3.8.1 算术运算符

运算符 说明 示例
+ 算数加运算符 1+3=4
- 算数减运算符 3-1=2
* 算数乘运算符 1*3=3
/ 算数除运算符,结果自动转换为浮点数 10/5=2.0
// 算数整除运算符,结果保留 int 类型 10//5=2
% 取余运算符 10%3=1
** 幂运算符,a**b 实为 a^b 2**3=8

3.8.2 赋值运算符

运算符 说明 示例
+= 变量增加指定的数值 a+=2 等价于 a=a+2
-= 变量减去指定的数值 a-=2 等价于 a=a-2
*= 变量乘指定的数值 a*=2 等价于 a=a*2
/= 变量除指定的数值 a/=2 等价于 a=a/2
//= 变量整除指定的数值 a//=2 等价于 a=a//2
%= 变量取余指定的数值 a%=2 等价于 a=a%2
**= 变量幂运算指定的数值 a**=2 等价于 a=a**2
:= 海象运算符,更新于 python3.8,用于在表达式内部为变量赋值 result = num_one + (num_two:=2)

3.8.3 比较运算符

运算符 说明
== 比较两个值是否相等
!= 比较两个值是否不相等
> 比较某个值是否大于另一个值
< 比较某个值是否小于另一个值
>= 比较某个值是否大于等于另一个值
<= 比较某个值是否小于等于另一个值

3.8.4 逻辑运算符

运算符 说明
AND 逻辑与运算符
OR 逻辑或运算符
NOT 逻辑非运算符

3.8.5 成员运算符

运算符 说明
IN 判断某个值是否位于某个成员中
NOT IN 判断某个值是否不位于某个成员中

3.8.6 位运算符

运算符 说明
>> 操作数按位右移
<< 操作数按位左移
& 按位与运算
| 按位或运算
^ 按位非运算
~ 按位取反

4. 流程控制语句

4.1 判断语句

4.1.1 if

if 语句语法如下:

py 复制代码
if 条件表达式:
    代码块

当条件表达式值为 True 时,执行代码块;若条件表达式值为 False 时,则跳过代码块

示例:判断输入的成绩是否合格,若合格,输出 "PASS"

py 复制代码
score=input("Please input score: ")
if int(score)>=60:
    print("PASS")

执行效果如下:

bash 复制代码
Please input score: # 88
PASS

Please input score: # 10
# 无输出

4.1.2 if-else

if-else 语句语法如下:

py 复制代码
if 条件表达式:
    代码块1
else:
    代码块2

当条件表达式值为 True 时,执行代码块1;若条件表达式值为 False 时,则执行代码块2

示例:判断输入的成绩是否合格,若合格,输出 "PASS";若不合格,输出 "FAIL"

py 复制代码
score=input("Please input score: ")
if int(score)>=60:
    print("PASS")
else:
    print("FAIL")

执行效果如下:

bash 复制代码
Please input score: # 88
PASS

Please input score: # 10
FAIL

4.1.3 if-elif-else

if-elif-else 语句语法如下:

py 复制代码
if 条件表达式1:
    代码块1
elif 条件表达式2:
    代码块2
elif 条件表达式3:
    代码块3
...
else:
    代码块n

从条件表达式1开始进行逻辑判断,直到结果为 True 时,执行对应的代码块

示例 1:对输入的成绩进行判断,90~100 输出 "A",80~89 输出 "B",70~79 输出 "C",60~69 输出 "D",其余输出 "E"

py 复制代码
score=input("Please input score: ")
score=int(score)

if score>=90:
    print("A")
elif score>=80:
    print("B")
elif score>=70:
    print("C")
elif score>=60:
    print("D")
else:
    print("E")

运行效果如下:

bash 复制代码
Please input score: # 100
A

Please input score: # 74
C

Please input score: # 50
E

示例 2:输入年份和月份,输出这个月有多少天

py 复制代码
year=int(input("Enter year: "))
month=int(input("Enter month: "))

if month in (1,3,5,7,8,10,12):
    print("31 Days")
elif month == 2:
    if year%400==0 or (year%4==0 and year%100!=0):
        print("29 Days")
    else:
        print("28 Days")
else:
    print("30 Days")

4.2 循环语句

4.2.1 while

while 语句语法如下:

py 复制代码
while 循环条件:
    循环体

当循环条件为 True 时,执行循环体,然后返回继续判断循环条件,如果仍为 True,则继续循环,如果为 False,则退出循环

示例:输出 1~10

py 复制代码
num=1
while num<=10:
    print(num,end=' ')
    num=num+1

输出效果如下:

py 复制代码
1 2 3 4 5 6 7 8 9 10

4.2.2 for

for 循环语句语法如下:

py 复制代码
for 变量名 in 范围:
    循环体

for 变量名 in range(其实范围,终止范围,变化规则)

示例:求和 1~100

py 复制代码
sum=0
for i in range(1,101):
    sum=sum+i
print(sum)

示例:求 1~100 的基数和

py 复制代码
sum=0
for i in range(1,101,2):
    sum=sum+i
print(sum)

4.2.3 continue

continue 关键字用于跳过本次循环,从 continue 所在位置以后的循环体代码将不会继续执行

示例:

py 复制代码
for i in range(3):
    print("Hello,world!")
    continue
    print("This wont be print")

输出如下:

bash 复制代码
Hello,world!
Hello,world!
Hello,world!

4.2.4 break

break 关键字用于退出当前循环,从 break 所在位置以后的循环体及循环判断将不会继续执行,程序将直接从循环后的代码继续运行

示例:

py 复制代码
for i in range(5):
    print("Hello,world!")
    if i == 2:
        break
    print("This only print 2 times")

输出如下:

bash 复制代码
Hello,world!
This only print 2 times
Hello,world!
This only print 2 times
Hello,world!

5. 字符与字符串

5.1 字符串样式

Python 中使用 ' '" "''' ''' 定义字符串,其中 ' '" " 通常用于定义单行字符串,''' ''' 通常用于定义多行字符串

如:

py 复制代码
print('Hello,world!') # 单引号,单行
print("Hello,world!") # 双引号,单行
print('''Hello,
World!''')            # 三引号,多行

输出如下:

bash 复制代码
Hello,world!
Hello,world!
Hello,
World!

!IMPORTANT

注:尽量避免出现同类型引号功能混用的状况,如 print('it's work!')

5.2 转义字符

转义字符使用 \ 加上特定的字符组成转义字符,以实现特殊的功能

常见的转义字符如下:

转义字符 功能
\b 退格(Backspace)
\n 换行
\v 纵向制表符
\t 横向制表符(Tab)
\r 回车(Enter)

5.3 字符串格式化

格式化字符串是指将的字符串转化为想要的格式,Python 中有三种格式化字符串的方式:使用 % 格式化、使用 format() 方法格式化和使用 f-string 格式化

5.3.1 %

使用 % 加上一个字符可以指定一个占位符,用于指定这个位置将要填入的数据的数据类型,常用的占位符类型如下:

格式占位符 格式
%c 字符
%s 字符串
%d 整型
%u 无符号整型
%o 无符号八进制整形
%x 无符号十六进制整形
%f 浮点型,可指定小数位数,默认为 6 位

填入数据,需要使用 字符串变量名 % 填入数据变量 的形式进行,如:

py 复制代码
txt = "I'm %d years old"
age = 20
print(txt % 20)  # 直接赋值
print(txt % age) # 使用变量赋值

如果遇到多个变量赋值,则需要使用 () 将变量扩起,示例

py 复制代码
name = "ZhangSan"
age = 20
info='''name: %s
age: %d'''

print(info % (name, age))

输出如下:

bash 复制代码
name: ZhangSan
age: 20

5.3.2 format()

Python 可以在字符串变量名后使用 format() 函数对字符串进行格式化,使用 {} 为需要填入的数据占位,示例:

py 复制代码
name = "ZhangSan"
age = 20
info='''name: {}
age: {}'''

print(info.format(name, age))

输出如下:

bash 复制代码
name: ZhangSan
age: 20

使用 {} 占位时,可以使用数字编号指定输入顺序,编号从 0 开始,示例:

py 复制代码
name = "ZhangSan"
age = 20
info='''name: {1}
age: {0}'''

print(info.format(age, name))

输出如下:

bash 复制代码
name: ZhangSan
age: 20

也可以创建新的名称辅助指定输入顺序。示例:

py 复制代码
name = "ZhangSan"
age = 20
sex = "male"

info='''userinfo:
name: {b}
age: {a}
sex: {c}'''

print(info.format(a=age, b=name, c=sex))

输出如下:

bash 复制代码
userinfo:
name: ZhangSan
age: 20
sex: male

5.3.3 f-string

f-string 提供了一种更为简洁的格式化字符串的方式,它在形式上以 fF 引领字符串,在字符串中使用 {变量名} 标明被替换的真实数据和其所在位置,示例:

py 复制代码
name = "ZhangSan"
age = 20

print(f'name: {name}  age: {age}')

输出如下:

bash 复制代码
name: ZhangSan  age: 20

5.4 查找、替换与处理

5.4.1 查找

Python 中提供了用于字符串查找操作的 find() 方法,该方法可查找字符串中是否包含子串,若包含则返回子串首次出现的索引位置,否则返回 -1,语法如下:

py 复制代码
字符串变量名.find(子字符串[,查找起始位置[,查找终止位置]])

示例:

py 复制代码
str = "1234567"
print(str.find('4'))
print(str.find('8'))

输出如下:

bash 复制代码
3
-1

5.4.2 替换

Python 中提供了用于实现字符串替换操作的 replace() 方法,该方法可将当前字符串中的指定子串替换成新的子串,并返回替换后的新字符串,语法如下:

py 复制代码
字符串变量名.replace(旧字符串,新字符串[,替换次数])

示例:

py 复制代码
str = "01101011"
print(str.replace('0','1'))

输出如下:

bash 复制代码
11111111

5.4.3 拆分

Python 中的 split() 方法可以按照指定分隔符对字符串进行分割,该方法会返回由分割后的子串组成的列表,语法格式如下:

py 复制代码
字符串变量名.split([拆分分隔符][,拆分次数])
# 默认使用 空格 作为拆分分隔符

示例:

py 复制代码
str = "192.168.100.10"
print(str.split('.'))

输出如下:

py 复制代码
['192', '168', '100', '10']

5.4.4 拼接

Python 中的 join() 方法使用指定字符连接字符串并生成一个新的字符串,语法格式如下:

py 复制代码
连接符.join(目标字符串)

示例:

py 复制代码
ch = '-'
str = "python"
print(ch.join(str))

输出结果如下:

bash 复制代码
p-y-t-h-o-n

在 Python 中,还可以使用 +* 号,以一种运算的方式将字符串拼接,示例:

bash 复制代码
str1 = "ba"
str2 = "na"
print(str1 + (str2 * 2))

输出结果如下:

bash 复制代码
banana

5.4.5 删除指定字符

字符串中可能会包含一些无用的字符(如空格),在处理字符串之前往往需要先删除这些无用的字符

Python中的 strip()lstrip()rstrip() 方法可以删除字符串中的指定字符

方法名 用途
strip() 移除字符串头尾指定的字符
lstrip() 移除字符串头部指定的字符
rstrip() 移除字符串尾部指定的字符

它们的语法格式均为 字符串变量名.函数名(字符/字符串)

示例:

py 复制代码
str1 = "abc11111abc"

print("source: \t" + str1)
print("strip(): \t" + str1.strip("abc"))
print("lstrip(): \t" + str1.lstrip("abc"))
print("rstrip(): \t" + str1.rstrip("abc"))

输出结果如下:

bash 复制代码
source: 	abc11111abc
strip(): 	11111       # 少了头和尾的 abc
lstrip(): 	11111abc    # 少了头的 abc
rstrip(): 	abc11111    # 少了尾的 abc

5.4.6 字符大小写转换

Python 中支持字母大小写转换的方法有 upper()lower()capitalize()title()

函数名 用途
upper() 将所有小写字母转换为大写字母
lower() 将所有大写字母转换为小写字母
capitalize() 将字符串中的第一个字母转换为大写,其余字符转换为小写
title() 将字符串中的每个单词的首字母转换为大写,其余字符转换为小写

示例:

py 复制代码
str1 = "python is the BEST language!"

print("source: \t\t" + str1)
print("upper(): \t\t" + str1.upper())
print("lower(): \t\t" + str1.lower())
print("capitalize(): \t" + str1.capitalize())
print("title(): \t\t" + str1.title())

输出结果如下:

bash 复制代码
source: 		python is the BEST language!
upper(): 		PYTHON IS THE BEST LANGUAGE! # 全部大写
lower(): 		python is the best language! # 全部小写
capitalize(): 	Python is the best language! # 首字母大写,其余小写
title(): 		Python Is The Best Language! # 每个单词的首字母大写,其余小写

5.4.7 字符串对齐

Python提供了 center()ljust()rjust() 这 3 个方法来设置字符串的对齐方式

函数名 语法格式 用途
center() center(width[,fillchar]) 返回长度为 width 的字符串,源字符串居中
ljust() ljust(width[,fillchar]) 返回长度为 width 的字符串,源字符串居左
rjust() rjust(width[,fillchar]) 返回长度为 width 的字符串,源字符串居右

fillchar 是填充空位的字符,默认为

示例:

py 复制代码
str1 = "12345678"

print("12length: \t|----------|")
print("center(): \t" + str1.center(12))
print("ljust(): \t" + str1.ljust(12, '-'))
print("rjust(): \t" + str1.rjust(12, '%'))
print("12length: \t|----------|")

输出结果如下:

bash 复制代码
12length: 	|----------|
center(): 	  12345678   # 居中,补空格
ljust(): 	12345678---- # 居左,补 -
rjust(): 	%%%%12345678 # 居右,补 %
12length: 	|----------|

6. 组合数据类型

6.1 序列

Python 中常用的序列类型有字符串(str)列表(list)元组(tuple)

Python 中的序列支持双向索引:正向递增索引和反向递减索引

  • 正向递增索引从左向右依次递增,第一个元素的索引为 0,第二个元素的索引为 1,以此类推
  • 反向递减索引从右向左依次递减,从右数第一个元素的索引为 -1,第二个元素的索引为 -2,以此类推。

列表元素可以是整型、浮点型、字符串等基本类型,也可以是列表、元组、字典等组合类型,还可以是其他自定义类型

列表元素的类型可以相同也可以不同

6.2 序列 - 列表

6.2.1 列表的基本使用

创建序列的语法如下:

py 复制代码
列表变量名=[列表元素1,列表元素2,...,列表元素n]

列表元素使用索引编号进行访问,语法如下:

py 复制代码
列表变量名[索引号]
列表变量名[[起始索引]:[终止索引]:[步进]]
# 起始索引:从指定位置开始,包含当前位置,默认为列表开始
# 终止索引:到指定位置结束,不包含当前位置,默认为列表末尾
# 步进:当前到下一个位置的间隔,默认为 1

使用示例:

py 复制代码
mylist=[1,2,3,4,5,6]
print(mylist)       # 输出整个列表
print(mylist[3])    # 输出第 4 个列表元素
print(mylist[-2])   # 输出倒数第 2 个列表元素
print(mylist[:3])   # 输出第 1~3 个元素
print(mylist[1::2]) # 从第 2 个元素开始输出到末尾,间隔 1 个元素

输出如下:

py 复制代码
[1, 2, 3, 4, 5, 6]
4
5
[1, 2, 3]
[2, 4, 6]

6.2.2 添加列表元素

Python 提供了 append()extend()insert() 这几个方法向列表末尾、指定位置添加元素

1. append()

append() 方法用于向列表末尾添加新的元素

示例:

py 复制代码
mylist = [1, 2, 3, 4, 5]
mylist.append(6)
print(mylist)

输出如下:

bash 复制代码
[1, 2, 3, 4, 5, 6]
2. extend()

extend() 在列表末尾一次性添加另一个列表中的所有元素,即使用新列表扩展原来的列表

示例:

py 复制代码
mylist_1 = [1, 2, 3, 4, 5]
mylist_2 = [6, 7, 8, 9]
mylist_1.extend(mylist_2)
print(mylist_1)

输出如下:

bash 复制代码
[1, 2, 3, 4, 5, 6, 7, 8, 9]
3. insert()

insert() 方法用于将新元素插入列表的指定位置,语法如下:

py 复制代码
列表变量名.insert(索引下标, 值s)

示例:

py 复制代码
mylist = [1, 2, 3, 5, 6]
mylist.insert(3, 4) # 在第 4 个位置插入数值 4
print(mylist)

输出如下:

bash 复制代码
[1, 2, 3, 4, 5, 6]

6.2.3 列表元素排序

列表的排序是将元素按照某种规定进行排列,常用的排序方法有 sort()reverse()sorted()

1. sort()

sort() 函数按照特定顺序对元素列表进行排序,语法如下:

py 复制代码
sort(key=排序依据,reverse=升降序)
# key 常用的参数
#   len: 长度
#
# reverse 常用的参数
#   True: 按照降序排序
#   False: 按照升序排序(默认)

6.2.4 删除列表元素

删除列表元素的常用方式有 del 语句、remove()pop()clear() 方法

函数/语句名 语法 用途
del del 列表变量名[目标下标] 删除指定位置的元素
remove() 列表变量名.remove(字符/字符串) 移除首个匹配到的元素
pop() 列表变量名.pop([下标]) 移除指定下标的元素,默认为最后一个元素
clear() 列表变量名.clear() 清空列表

示例:

py 复制代码
list1 = ["Jarry", "Jarry", "Tom", "Spike"]
print("source list: ", list1)
del list1[2]
print("del list1[2]: ", list1)

list1 = ["Jarry", "Jarry", "Tom", "Spike"] # 重新赋值
list1.remove('Jarry')
print("list1.remove('Jarry'): ", list1)

list1 = ["Jarry", "Jarry", "Tom", "Spike"] # 重新赋值
list1.pop(2)
print("list1.pop(2): ", list1)

list1 = ["Jarry", "Jarry", "Tom", "Spike"] # 重新赋值
list1.clear()
print("list1.clear(): ", list1)

输出结果如下:

bash 复制代码
source list:  ['Jarry', 'Jarry', 'Tom', 'Spike']
del list1[2]:  ['Jarry', 'Jarry', 'Spike']
list1.remove('Jarry'):  ['Jarry', 'Tom', 'Spike']
list1.pop(2):  ['Jarry', 'Jarry', 'Spike']
list1.clear():  []

6.2.5 列表推导式

列表推导式是符合 Python 语法规则的复合表达式,它用于以简洁的方式根据已有的列表构建满足特定需求的列表

语法如下:

py 复制代码
[表达式 for 变量名 in 列表变量名]

示例:将一个列表中的数值转换为自身的平方

py 复制代码
list1 = [1,2,3,4,5,6,7,8]
list2 = [num * num for num in list1]
print("list1: ", list1)
print("list2: ", list2)

输出结果如下:

bash 复制代码
list1:  [1, 2, 3, 4, 5, 6, 7, 8]
list2:  [1, 4, 9, 16, 25, 36, 49, 64]

列表推导式中可以嵌套判断和循环语句,如 iffor

示例 1:生成一个包含 1 到 10 之间所有偶数的平方的列表

py 复制代码
list1 = [1,2,3,4,5,6,7,8,9,10]
list2 = [num * num for num in list1 if num%2==0]
print("list1: ", list1)
print("list2: ", list2)

输出结果如下:

bash 复制代码
list1:  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2:  [4, 16, 36, 64, 100]

示例 2:生成一个包含 1 到 3 和 4 到 6 之间所有数字之和的列表(即计算所有 x + y,其中 x 来自 1~3,y 来自 4~6)

py 复制代码
list1 = [1,2,3]
list2 = [4,5,6]
list3 = [x+y for x in list1 for y in list2]
print("list1: ", list1)
print("list2: ", list2)
print("list3: ", list3)

输出结果如下:

bash 复制代码
list1:  [1, 2, 3]
list2:  [4, 5, 6]
list3:  [5, 6, 7, 6, 7, 8, 7, 8, 9]

示例 3:有 list1list2 两个列表,计算当 list1 的值小于 list2 时,两值的乘积

py 复制代码
list1 = [1,2,3,4,5]
list2 = [1,2,3,4,5]
list3 = [x*y for x in list1 for y in list2 if x<y]
print("list1: ", list1)
print("list2: ", list2)
print("list3: ", list3)

输出结果如下:

bash 复制代码
list1:  [1, 2, 3, 4, 5]
list2:  [1, 2, 3, 4, 5]
list3:  [2, 3, 4, 5, 6, 8, 10, 12, 15, 20]

6.3 序列 - 元组

元组的表现形式为一组包含在圆括号 () 中、由逗号分隔的元素,元组中元素的个数、类型不受限制。使用圆括号可以直接创建元组,还可以使用内置函数 tuple() 构建元组

当使用圆括号 () 创建元组时,如果元组中只包含一个元素,那么需要在该元素的后面添加逗号,从而保证 Python 解释器能够识别其为元组类型

示例:

py 复制代码
t1 = ()                 # 空元组
t2 = (1,)               # 包含单个元素的元组
t3 = (1,2,3)            # 包含多个元素的元组
t4 = (1,'h',('o',2))    # 元组嵌套

使用内置函数 tuple() 也可以创建元组,当函数的参数列表为空时该函数常见空元组,当参数为可迭代对象时该函数创建非空元组

示例:

py 复制代码
t1 = tuple()            # 创建空元组
t2 = tuple([1,2,3])     # 利用列表创建元组(1,2,3)
t3 = tuple('python')    # 利用字符串创建元组('p','y','t','h','o','n')
t4 = tuple(range(5))    # 利用可迭代对象创建元组(0,1,2,3,4)

与列表相同,Python支持通过索引和切片访问元组的元素,也支持在循环中遍历元组

py 复制代码
print(t2[1])    # 以索引方式访问元组元素
print(t3[2:5])  # 以切片方式访问元组元素
for data in t3: # 在循环中遍历元组
    print(data,end='')

!IMPORTANT

元组是不可变类型,元组中的元素不能修改,即它不支持添加元素,删除元素和排序操作

6.4 集合

Python 集合具备确定性、互异性和无序性三个特性

Python 要求放入集合中的元素必须是不可变类型,Python 中的整型、浮点型、字符串类型和元组属于不可变类型,列表、字典及集合本身都属于可变的数据类型

  • 确定性:给定一个集合,那么任何一个元素是否在集合中就确定了
  • 互异性:集合中的元素互不相同
  • 无序性:集合中的元素没有顺序,顺序不同但元素相同的集合可视为同一集合

6.5 映射

映射类型以键值对的形式存储元素,键值对中的键与值之间存在映射关系

字典(dict)是 Python 唯一的内置映射类型,字典的键必须遵守以下两个原则:

  • 每个键只能对应一个值,不允许同一个键在字典中重复出现
  • 字典中的键是不可变类型

7. 函数

7.1 函数的定义与调用

函数的定义语法如下:

py 复制代码
def 函数名([参数列表]):
    函数体
    [return 语句]

函数分为有参函数和无参函数,有参函数的形参列表中需要包含参数,无参函数的形参列表为空

如果需要将函数运算的结果返回给调用函数,则需要加上 return 语句和要返回的值

示例:

py 复制代码
# 无参函数
def hello():
    print("Hello,world")

# 有参函数
def add(a,b):
    result = a + b
    return result # 返回 result

函数在定义完成后不会立刻执行,直到被程序调用时才会执行,调用函数只需要写下函数名即可,如果是有参函数还需要加上传递的参数

示例:

py 复制代码
# 无参函数
def hello():
    print("Hello,world")

# 有参函数
def add(a,b):
    result = a + b
    return result # 返回 result

a=1
b=2

hello()
print(add(a,b))

运行结果如下:

bash 复制代码
Hello,world
3

函数内可以嵌套定义函数

7.2 函数参数传递

我们通常将定义函数时设置的参数称为形式参数 ,简称形参 ;将调用函数时传入的参数称为实际参数 ,简称实参

函数的参数传递是指将实际参数传递给形式参数的过程

函数参数的传递可以分为位置参数传递关键字参数传递默认参数传递参数的打包与解包 以及混合传递五种方法

7.2.1 位置参数传递

函数在被调用时会将实参按照相应的位置依次传递给形参,也就是说将第一个实参传递给第一个形参,将第二个实参传递给第二个形参,以此类推

示例:

py 复制代码
def add(a,b):
    result = a + b
    return result

print(add(1,2))

7.2.2 关键字参数传递

关键字参数的传递是通过 "形参=实参" 的格式将实参与形参相关联,将实参按照相应的关键字传递给形参

示例:

py 复制代码
def connect(ip,port):
    print(f'设备 {ip}:{port} 连接!')

connect(ip='127.0.0.1', port=8080)

从 Python 3.8 开始新增了仅限位置形参的语法,使用符号 /* 来限定部分形参只接收采用位置传递方式的实参

  • / 前的形参必须使用位置参数传递
  • * 后的形参必须使用关键字参数传递

示例:

py 复制代码
def func(a,/,b,*,c):
    print(a,b,c)
# a 仅限使用参数传递
# c 仅限使用关键字传递

func(10,20,c=30)    # Success
func(10,b=20,c=30)  # Success
# func(a=10,b=20,c=30)  # Failed
# func(10,20,30)        # Failed

7.2.3 默认参数传递

函数在定义时可以指定形参的默认值,如此在被调用时可以选择是否给带有默认值的形参传值,若没有给带有默认值的形参传值,则直接使用该形参的默认值

示例:

py 复制代码
def connect(ip,port=8080):
    print(f'设备 {ip}:{port} 连接!')
connect(ip="127.0.0.1")             # 未传递参数,使用默认参数
connect(ip="127.0.0.1",port=3306)   # 传递参数,使用传递参数

输出结果如下:

bash 复制代码
设备 127.0.0.1:8080 连接!
设备 127.0.0.1:3306 连接!

7.2.4 参数的打包与解包

打包如果函数在定义时无法确定需要接收多少个数据,那么可以在定义函数时为形参添加 "*" 或 "**":

1. 打包
  • *: 以元组的形式打包多个值
  • **: 以字典的形式打包多个值

示例:

py 复制代码
def func1(*args):
    print(args)
    print(type(args))

def func2(**args):
    print(args)
    print(type(args))

func1(1,2,3,4,5)
func2(a=1,b=2,c=3,d=4)

输出结果如下:

bash 复制代码
(1, 2, 3, 4, 5)
<class 'tuple'>
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
<class 'dict'>
2. 解包

解包与打包的符号用法一致,只是方向不同

示例:

py 复制代码
def func1(a,b,c,d,e):
    print(a,b,c,d,e)

def func2(a,b,c,d,e):
    print(a,b,c,d,e)

nums1 = [1,2,3,4,5]
nums2 = {'a':1,'b':2,'c':3,'d':4,'e':5}

func1(*nums1)
func2(**nums2)

输出结果如下:

bash 复制代码
1 2 3 4 5
1 2 3 4 5

7.2.5 返回值

函数中的 return 语句会在函数结束时将数据返回给程序,同时让程序回到函数被调用的位置继续执行

示例:

py 复制代码
num1 = int(input("Enter a number: "))
num2 = int(input("Enter another number: "))

def add(num1, num2):
    return num1 + num2 # 将运算结果返回给上一层调用

print(add(num1, num2)) # 返回值将直接被输出

输出结果如下:

bash 复制代码
Enter a number: # 3
Enter another number: # 5
8

如果遇到需要返回多个值,则需要在这些值之间加上 , 进行区分,且返回值类型会变为元组类型

示例:

py 复制代码
def func():
    return 1, 2

print(func(), type(func()))

输出结果如下:

bash 复制代码
(1, 2) <class 'tuple'>

7.3 变量作用域(scope)

变量并非在程序的任意位置都可以被访问,其访问权限取决于变量定义的位置,其所处的有效范围 称为变量的作用域

7.3.1 局部变量与全局变量

根据作用域 的不同,变量可以划分为局部变量全局变量

  • 局部变量(Local Variable):一般指函数内部定义的变量,只能在函数内部被使用
  • 全局变量(Global Variable):可以在整个程序的范围内起作用,可以在程序的任意位置被访问,它不会受到函数范围的影响

示例:

py 复制代码
num = 10  # 全局变量

def func1():
    num = 5  # 局部变量(只在 func1 内部有效)
    print("func1 内部的 num:", num)

def func2():
    print("func2 访问到的 num:", num)  # 未定义局部变量时,会访问全局变量

print("全局 num:", num)
func1()  # 调用 func1,打印局部变量
func2()  # 调用 func2,打印全局变量
print("函数调用后,全局 num 仍然是:", num)

输出结果如下:

bash 复制代码
全局 num: 10
func1 内部的 num: 5
func2 访问到的 num: 10
函数调用后,全局 num 仍然是: 10

7.3.2 global 关键字

如果想在函数内部修改全局变量的值,需要使用关键字 global,示例:

py 复制代码
num = 10

def change_global():
    global num
    num = 20  # 修改全局变量
    print("在函数中修改 num:", num)

change_global()
print("修改后的全局 num:", num)

输出结果如下:

bash 复制代码
在函数中修改 num: 20
修改后的全局 num: 20

7.3.3 nonlocal 关键字

使用 nonlocal 关键字可以在局部作用域中修改嵌套作用域中定义的变量,示例:

py 复制代码
def outer():
    num = 10
    def inner():
        nonlocal num  # 声明使用外层函数的变量(非全局)
        print("inner 内访问 num:", num)
        num = 20
        print("inner 内修改 num:", num)
    inner()
    print("outer 内的 num:", num)

outer()

输出结果如下:

bash 复制代码
inner 内访问 num: 10
inner 内修改 num: 20
outer 内的 num: 20

7.4 匿名函数 lambda

匿名函数是一类无需定义标识符的函数,它与普通函数一样可以在程序的任何位置使用。Python 中使用 lambda 关键字定义匿名函数

匿名函数与普通函数的主要区别如下:

  • 普通函数使用 def 定义,有函数名;匿名函数使用 lambda 定义,无函数名
  • 普通函数的函数体可以包含多条语句;匿名函数的函数体只能是一个表达式,且自动作为返回值
  • 匿名函数通常用于一次性使用或简短逻辑的场景,比如作为函数参数

语法如下:

py 复制代码
[变量名 = ]lambda [形参列表]: 表达式
# 一般建议将匿名函数赋值给变量,方便重复使用

示例:

py 复制代码
temp = lambda x: pow(x,2)
print("2 ^ 2 =", temp(2))

输出结果如下:

bash 复制代码
2 ^ 2 = 4

8. 文件处理

8.1 文件

文件在计算机中应用广泛,计算机中的文件是以硬盘等外部介质为载体,存储在计算机中的数据的集合,文本文档、图片、程序、音频等都是文件

类似于程序中使用的变量,计算机中的每个文件也有唯一确定的标识,以便识别和引用文件

文件标识用于找到计算机中唯一确定的文件,其由文件路径、文件名主干、文件扩展名组成

文件类型根据数据的逻辑存储结构,人们将计算机中的文件分为文本文件和二进制文件

  • 文本文件:专门存储文本字符数据(使用记事本)
  • 二进制文件:不能直接使用文字处理程序正常读写,必须先了解其结构和序列化规则,再设计正确的反序列化规则,才能正确获取文件信息

总结:二进制文件和文本文件这两种类型的划分基于数据逻辑存储结构而非物理存储结构,计算机中的数据在物理层面都以二进制形式存储

8.2 Python 标准文件

Python 的 sys 模块中定义了 3 个标准文件,分别为:

  • stdin:标准输入文件,标准输入文件对应输入设备,如键盘
  • stdout:标准输出文件
  • stderr:标准错误文件,标准输出文件和标准错误文件对应输出设备,如显示器

在解释器中导入 sys 模块后,便可对标准文件进行操作

示例:

py 复制代码
import sys
file = sys.stdout
file.write('lucky cloud')

8.3 文件基本操作

将数据写入到文件之前需要先打开文件;数据写入完毕后需要将文件关闭以释放计算机内存

8.3.1 打开文件

内置函数 open() 用于打开文件,该方法的声明如下

py 复制代码
open(FILE[, mode='MODE', buffering=BUFFERING])
# FILE: 文件路径
# MODE: 文件打开模式,可组合,可填写参数如下:
#   - r: 以只读方式打开,默认
#   - w: 以只写方式打开
#   - a: 以追加方式打开
#   - b: 以二进制形式打开
#   - +: 以更新方式打开(可读可写)
# BUFFERING: 设置访问文件的缓冲方式。取值为 0 或 1

示例:在 E:\ 创建一个文件 1.txt,打开这个文件

py 复制代码
file = open("E:\\1.txt")
print(file)

输出结果如下:

bash 复制代码
# 如果文件存在,则会返回正常结果
<_io.TextIOWrapper name='E:\\1.txt' mode='r' encoding='cp936'>

# 如果文件不存在,则会抛出异常
FileNotFoundError: [Errno 2] No such file or directory: 'E:\\1.txt'

8.3.2 关闭文件

Python 可通过 close() 方法关闭文件,也可以使用 with 语句实现文件的自动关闭

close() 方法,是文件对象的内置方法,使用语法如下:

py 复制代码
文件变量名.close()

with 语句,可预定义清理操作,以实现文件的自动关闭,示例:

py 复制代码
with open('E:\\1.txt') as f:
    print('文件关闭')
    pass

8.3.3 文件读写

Python 提供了一系列读写文件的方法,包括读取文件的 read()readline()readlines() 方法和写文件的 write()writelines()

1. read()

read() 方法可以从指定文件中读取指定字节的数据,语法格式如下:

py 复制代码
read([SIZE])
# SIZE: 指定读取的数据长度,单位:Byte,默认读取全部数据

示例:

py 复制代码
# 打开文件
file = open("E:\\1.txt")
# 读取文件
str = file.read()
# 输出文件内容
print(str)
# 关闭文件
file.close()

##### 也可以 #####
with open("E:\\1.txt") as f:
    print(f.read(2)) # 指定获取长度
    print(f.read())  # 获取所有数据
2. readline()

readline() 方法可以从指定文件中读取一行数据,其语法格式如下:

py 复制代码
文件变量名.readline()

示例:修改 1.txt 文件内容为:

bash 复制代码
Nice to meet you!
Nice to meet you, too!
Nice to meet you, three!
Nice to meet you, four!
py 复制代码
file = open("E:\\1.txt")
str = file.readline()
print(str)
file.close()

输出如下:

bash 复制代码
Nice to meet you!
3. readlines()

readlines() 方法可以一次读取文件中的所有数据,若读取成功,该方法会返回一个列表,文件中的每一行对应列表中的一个元素

函数语法格式如下:

py 复制代码
文件变量名.readlines()
4. write()

write() 方法可以将指定字符串写入文件,其语法格式如下

py 复制代码
write(DATA)

若数据写入成功,write() 方法会返回本次写入文件的数据的字节数

示例:在文件中添加 "Nice to meet you, too!

py 复制代码
text='\nNice to meet you, too!'

with open("E:\\1.txt","r+") as f:
    # 读取文件
    f.seek(0)
    str1 = f.read()
    print("===== Original content =====")
    print(str1)

    # 写入字符串
    f.write(text)

    # 再次读取文件
    f.seek(0) # 将文件指针移动到文件头
    str2 = f.read()
    print("\n===== Content after writing =====")
    print(str2)

输出结果如下:

py 复制代码
===== Original content =====
Nice to meet you!

===== Content after writing =====
Nice to meet you!
Nice to meet you, too!
5. writelines()

writelines() 方法用于将行列表写入文件,其语法格式如下

py 复制代码
writelines(LINES)
  • 以上格式中的参数 lines 表示要写入文件中的数据,该参数可以是一个字符串或者字符串列表
  • 若写入文件的数据在文件中需要换行,需要显式指定换行符

示例:

py 复制代码
textlines=['\nNice to meet you, three!', '\nNice to meet you, four!']

with open("E:\\1.txt","r+") as f:
    # 读取文件
    f.seek(0) # 将文件指针移动到文件头
    str1 = f.read()
    print("===== Original content =====")
    print(str1)

    # 写入字符串
    f.writelines(textlines)

    # 再次读取文件
    f.seek(0) # 将文件指针移动到文件头
    str2 = f.read()
    print("\n===== Content after writing =====")
    print(str2)

输出效果如下:

bash 复制代码
===== Original content =====
Nice to meet you!
Nice to meet you, too!

===== Content after writing =====
Nice to meet you!
Nice to meet you, too!
Nice to meet you, three!
Nice to meet you, four!

8.3.4 数据定位读写

有以下代码:

py 复制代码
# 文件内容: ABCDEFGHIJKLMN
with open("E:\\1.txt","r+") as f:
    str1 = f.read(2)
    print(str1)
    str2 = f.read(3)
    print(str2)

输出内容如下:

bash 复制代码
AB
CDE

read() 方法读取了文件 luckycloud.txt,结合代码与程序运行结果进行分析,可以发现 read() 方法第 1 次读取了 2 个字符,第 2 次从第 3 个字符开始读取了 5 个字符

在文件的一次打开与关闭之间进行的读写操作是连续的,程序总是从上次读写的位置继续向下进行读写操作

每个文件对象都有一个称为"文件读写位置"的属性,该属性会记录当前读写的位置,文件读写位置默认为 0,即在文件头

Python提供了一些获取与修改文件读写位置的方法,以实现文件的定位读写:

  • tell():获取文件当前的读写位置
  • seek():控制文件的读写位置
1. tell()

tell() 方法用于获取文件当前的读写位置,示例:

py 复制代码
with open("E:\\1.txt","r+") as f:
    str1 = f.read(2)
    print(str1)
    print(f.tell())
    str2 = f.read(3)
    print(str2)

输出结果如下:

bash 复制代码
AB
2
CDE
2. seek()

seek() 方法用于可控制文件的读写位置,实现文件的随机读写,语法格式如下

py 复制代码
seek(offset, from)
# offset: 表示偏移量,即读写位置需要移动的字节数
# from: 用于指定文件的读写位置,可设置参数为:
#   0: 文件头
#   1: 当前位置
#   2: 文件尾

示例:

py 复制代码
# 文件内容:ABCDEFG
with open("E:\\1.txt","r+") as f:
    str1 = f.read(3)
    print(str1)
    f.seek(0) # 将文件指针指向文件头
    str2 = f.read(3)
    print(str2)
    f.seek(0,1) # 使用当前位置继续读写
    str3 = f.read(3)
    print(str3)
    f.seek(1,0) # 将文件指针指向文件头,向右偏 1 个字符
    str4 = f.read(3)
    print(str4)

输出结果如下:

bash 复制代码
ABC
ABC
DEF
BCD

8.3.5 文件与目录管理

对于用户而言,文件和目录以不同的形式展现,但对计算机而言,目录是文件属性信息集合,它本质上也是一种文件

os 模块中定义了与文件操作相关的函数,利用这些函数可以实现删除文件、文件重命名、创建/删除目录、获取当前目录、更改默认目录与获取目录列表等操作

1. remove()

使用 os 模块的 remove() 函数可删除文件,该函数要求目标文件存在,语法如下:

py 复制代码
remove(FILE)

示例:

py 复制代码
import os
os.remove("E:\\1.txt.bak")
2. rename()

使用 os 模块中的 rename() 函数可以更改文件名,该函数要求目标文件已存在,语法如下:

py 复制代码
rename(FILE, NEW_FILE)

!NOTE

  • 当目标文件存在时,无法重命名
  • 源文件名与目标文件名均为文件路径形式

示例:

py 复制代码
import os
os.rename("E:\\1.txt.bak", "E:\\1.file")
3. getcwd()

os 模块中的 getcwd() 函数用于获取当前目录,即 Python 当前的工作路径,调用该函数可获取当前工作目录的绝对路径,示例:

py 复制代码
import os
print(os.getcwd())
4. mkdir() / rmdir()

os 模块中的 mkdir() 函数用于创建目录,rmdir() 函数用于删除目录,这两个函数的参数都是目录名称

mkdir() 函数用于在当前目录下创建目录,需要注意,待创建的目录不能与已有目录重名,否则将创建失败

示例:在 E:\ 下创建一个目录 py1

py 复制代码
import os
os.mkdir("E:\\py1")

rmdir() 用于删除目录,示例:将刚刚创建的目录删除

py 复制代码
import os
os.rmdir("E:\\py1")
5. chdir()

os 模块中的 chdir() 函数用于更改默认目录。若在对文件或文件夹进行操作时传入的是文件名而非路径名,Python 解释器会从默认目录中查找指定文件,或将新建的文件放在默认目录下。若没有特别设置,当前目录即为默认目录

使用 chdir() 函数更改默认目录为F盘,再次使用 getcwd() 函数获取当前目录,示例:

py 复制代码
import os
print('更改前默认路径:',os.getcwd())
os.chdir('F:\\')
print('更改后默认路径:',os.getcwd())
6. listdir()

实际使用中常常需要先获取指定目录下的所有文件,再对目标文件进行相应操作。os 模块中提供了 listdir() 函数,使用该函数可方便快捷地获取指定目录下所有文件的文件名列表

示例:

py 复制代码
import os
print(os.listdir("E:\\py1"))

8.3.6 数据维度与数据格式化

1. 数据维度

根据组织数据时与数据有联系的参数的数量,数据可分为一维数据、二维数据和多维数据

  • 一维数据:具有对等关系的一组线性数据,如一维列表、一维元组、集合
  • 二维数据:二维数据关联参数的数量为 2,如矩阵、二维数组、二维列表、二维元组
  • 多维数据:利用键值对等简单的二元关系展示数据间的复杂结构,如字典
2. 一二维数据的存储与读写

程序中与数据相关的操作分为数据的存储与读写,下面我们就一起掌握如何存储与读写不同维度的数据

数据通常存储在文件中,为了方便后续的读写操作,数据通常需要按照约定的组织方式进行存储。

一维数据呈线性排列,一般用特殊字符分隔,例如:

  • 使用' '分隔:成都 杭州 重庆 武汉 苏州 西安 天津
  • 使用,分隔:成都,杭州,重庆,武汉,苏州,西安,天津
  • 使用&分隔:成都&杭州&重庆&武汉&苏州&西安&天津

一维数据的存储需要注意以下几点:

  • 同一文件或同组文件一般使用同一分隔符分隔
  • 分隔数据的分隔符不应出现在数据中
  • 分隔符为英文半角符号,一般不使用中文符号作为分隔符

二维数据可视为多条一维数据的集合,当二维数据只有一个元素时,这个二维数据就是一维数据

CSV(Commae-Separeted Values,逗号分隔值)是国际上通用的一二维数据存储格式

CSV 格式规范:

  • 以纯文本形式存储表格数据
  • 文件的每一行对应表格中的一条数据记录
  • 每条记录由一个或多个字段组成
  • 字段之间使用逗号(英文、半角)分隔
  • CSV 也称字符分隔值,具体示例如下:
bash 复制代码
姓名,语文,数学,英语,理综
刘备,124,137,145,260
张飞,116,143,139,263
关羽,120,130,148,255
周瑜,115,145,131,240
诸葛亮,123,108,121,235
黄月英,132,100,112,210

CSV 广泛应用于不同体系结构下网络应用程序之间表格信息的交换中,它本身并无明确格式标准,具体标准一般由传输双方协议决定

Windows 平台中 CSV 文件的后缀名为 .csv,可通过 Office Excel 或记事本打开。

!TIP

尝试创建一个文件 1.csv,并将样例文本复制粘贴进去,再用 Excel 打开这个文件,会发现自动生成了一个 Excel 表格

但请注意,文件的编码格式应当为 ANSI,否则会出现乱码

Python 在程序中读取 .csv 文件后会以二维列表形式存储其中内容

示例:

py 复制代码
import chardet

with open('E:\\1.csv','rb') as f:
    raw_data = f.read()
    encoding = chardet.detect(raw_data)['encoding']

with open('E:\\1.csv',encoding=encoding,errors='ignore') as f:
    lines = []
    for line in f:
        line = line.replace('\n','')
        lines.append(line.split(','))
    print(lines)

输出结果如下:

bash 复制代码
[['姓名', '语文', '数学', '英语', '理综'], ['刘备', '124', '137', '145', '260'], ['张飞', '116', '143', '139', '263'], ['关羽', '120', '130', '148', '255'], ['周瑜', '115', '145', '131', '240'], ['诸葛亮', '123', '108', '121', '235'], ['黄月英', '132', '100', '112', '210']]

示例:

py 复制代码
import chardet

#默认字符集处理
def open_file(address):
    with open(address,'rb') as f:
        raw_data = f.read()
        return chardet.detect(raw_data)['encoding']

addr = 'E:\\1.csv'
with open(addr,encoding=open_file(addr),errors='ignore') as f:
    file_new = open('E:\\1.csv','w+')
    lines = []
    for line in f:
        line = line.replace('\n','')
        lines.append(line.split(','))

    #添加表头字段
    lines[0].append('total')
    #添加总计
    for i in range(len(lines)-1):
        idx = i+1
        sun_score = 0
        for j in range(len(lines[idx])):
            if lines[idx][j].isnumeric():
                sun_score += int(lines[idx][j])
        lines[idx].append(str(sun_score))

for line in lines:
    print(line)
    file_new.write(','.join(line)+'\n')
3. 多维数据格式化

为了直观地表示多维数据,也为了便于组织和操作,三维及以上的多维数据统一采用键值对的形式进行格式化

网络平台上传递的数据大多是高维数据,JSON是网络中常见的高维数据格式。JSON格式的数据遵循以下语法规则

  • 数据存储在键值对(key:value)中,例如"姓名": "张飞"
  • 数据的字段由,分隔,例如"姓名": "张飞", "语文": "116"
  • 一个{}保存一个 JSON 对象,例如{"姓名": "张飞", "语文": "116"}
  • 一个[]保存一个数组,例如[{"姓名": "张飞", "语文": "116"}]

利用 JSON 模块的 dumps() 函数和 loads() 函数可以实现 Python 对象和 JSON 数据之间的转换,这两个函数的具体功能如表所示

函数 功能
dumps() 对 Python 对象进行转码,将其转化为 JSON 字符串
loads() 将 JSO N字符串解析为 Python 对象

Python 对象与 JSON 数据转化时的类型对照表

Python对象 JSON数据
dict object
list,tuple array
str,unicode string
int,long,float number
True true
False false
None null

使用 dumps() 函数对 Python 对象进行转码

示例:

py 复制代码
import json
pyobj = [[1,2,3],10,3,14,'tom',{'java':98,'python':100},True,False,None]
jsonobj = json.dumps(pyobj)
print(jsonobj)

输出结果如下:

bash 复制代码
[[1, 2, 3], 10, 3, 14, "tom", {"java": 98, "python": 100}, true, false, null]

使用 loads() 函数将 JSON 数据转换为符合 Python 语法要求的数据类型

py 复制代码
import json

pyobj = [[1,2,3],10,3,14,'tom',{'java':98,'python':100},True,False,None]
jsonobj = json.dumps(pyobj)
print(jsonobj)

# 反序列化操作
new_obj = json.loads(jsonobj)
print(new_obj)

输出结果如下:

bash 复制代码
[[1, 2, 3], 10, 3, 14, "tom", {"java": 98, "python": 100}, true, false, null]
[[1, 2, 3], 10, 3, 14, 'tom', {'java': 98, 'python': 100}, True, False, None]

9. 面向对象

9.1 类和对象

面向对象编程有两个非常重要的概念:类和对象

  • 对象映射现实中真实存在的事物,如一本书
  • 具有相同特征和行为的事物的集合统称为类

对象是根据类创建的,一个类可以对应多个对象,类是对象的抽象,对象是类的实例

9.1.1 类

类是由 3 部分组成:

  • 类的名称:大驼峰命名法,首字母一般大写,比如 Person
  • 类的属性:用于描述事物的特征,比如姓名,性别,身高,体重等(静态描述)
  • 类的方法:用于描述事物的行为,比如吃饭,睡觉,健身,娱乐等(动态描述)

类定义语法如下:

py 复制代码
class 类名:
    属性名 = 值
    def 方法名(self): 
        方法体

示例:

py 复制代码
class car:              # 类名: car
    wheel = 4           # 类属性 wheel 值为 4
    def drive(self):    # 类方法 drive()
        print("Driving")

9.1.2 对象

根据类创建对象的语法格式如下:

py 复制代码
对象名 = 类名()

示例:

py 复制代码
class Car:
    wheel = 4
    def drive(self):
        print("Driving")

c1 = Car()      # 创建对象
print(c1.wheel) # 输出对象属性
c1.drive()      # 输出对象方法

输出结果如下:

py 复制代码
4
Driving

9.2 类的成员

9.2.1 属性

属性按声明的方式可以分为两类:类属性和实例属性

1. 类属性

类属性指声明在类内部、方法外部的属性。可以通过类或对象进行访问,但只能通过类进行修改

示例:

py 复制代码
class Car:
    wheels = 4  # 属性
    def drive(self):  # 方法
        print("Driving")

c1 = Car()
print(Car.wheels)
print(c1.wheels)

# 通过类修改类属性
Car.wheels = 3
print(Car.wheels)   # 类的属性将受到影响
print(c1.wheels)    # 对象的属性将受到影响

# 通过对象修改类属性
c1.wheels = 4
print(Car.wheels)   # 类的属性将不受到影响
print(c1.wheels)    # 对象的属性将受到影响

输出结果如下:

py 复制代码
4
4
3
3
3
4
2. 实例属性

实例属性是在方法内部声明的属性,只能通过对象修改和访问,Python 支持动态添加实例属性

示例:

py 复制代码
class Car:
    def drive(self):  # 方法
        self.wheels = 4 # 实例属性

# 访问属性
c1 = Car()
c1.drive()
print(c1.wheels)
# print(Car.wheels) # ERROR

# 修改属性
c1.wheels = 3
print(c1.wheels)

# 动态添加属性
c1.color = "green"
print(c1.color)

输出结果如下:

py 复制代码
4
3
green

9.2.2 方法

Python 中的方法按定义方式和用途可以分为三类:实例方法、类方法和静态方法

1. 实例方法

实例方法形似函数,但它定义在类内部,以 self 为第一个形参,self 参数代表对象本身,只能通过对象调用

示例:

py 复制代码
class Car:
    def drive(self):
        print("Driving")

c1 = Car()
c1.drive()
# Car.drive() # ERROR
Car.drive(c1)

输出结果如下:

bash 复制代码
Driving
Driving
2. 类方法

类方法是定义在类内部,使用装饰器 @classmethod 修饰的方法,第一个参数为cls,代表类本身,可以通过类和对象调用

示例:

py 复制代码
class Car:
    def drive(self): # 方法
        print("Driving")

    @classmethod
    def stop(cls): # 类方法
        print("Stopping")

c1 = Car()
c1.stop()   # 使用对象调用类方法
Car.stop()  # 使用类调用类方法

输出结果如下:

bash 复制代码
Stopping
Stopping

类方法中可以使用 cls 访问和修改类属性的值,示例:

py 复制代码
class Car:
    color = 'red'

    @classmethod
    def func(cls): # 类方法
        print(cls.color)
        cls.color = "blue"
        print(cls.color)

c1 = Car()
c1.func()

输出结果如下:

bash 复制代码
red
blue
3. 静态方法

静态方法是定义在类内部,使用装饰器 @staticmethod 修饰的方法,没有任何默认参数

静态方法可以通过类和对象调用,独立于类所存在

示例:

py 复制代码
class Car:
    @staticmethod
    def drive():
        print("Driving")

c1 = Car()
c1.drive()
Car.drive()

输出结果如下:

bash 复制代码
Driving
Driving

静态方法内部不能直接访问属性或方法,但可以使用类名访问类属性或调用类方法

示例:

py 复制代码
class Car:
    wheels = 4 # 类属性

    @staticmethod
    def get_wheels():
        print(f"{Car.wheels}")

c1 = Car()
c1.get_wheels()
Car.get_wheels()

输出结果如下:

bash 复制代码
4
4

9.2.3 私有成员

类的成员默认是公有成员,可以在类的外部通过类或对象随意地访问,这样显然不够安全,为了保证类中数据的安全,Python 支持将公有成员改为私有成员,在一定程度上限制在类的外部对类成员的访问。

Python 通过在类成员的名称前面添加 __ 的方式来表示私有成员,语法格式如下:

py 复制代码
__属性名/方法名

示例:

py 复制代码
class Car:
    __wheels = 4 # 私有属性
    def __drive(self): # 私有方法
        print("Driving")

    def test(self):
        # 使用类公有方法访问类私有方法
        print(f"Wheels: {self.__wheels}")
        self.__drive()

c1 = Car()
c1.test()

输出结果如下:

bash 复制代码
Wheels: 4
Driving

9.3 特殊方法

类中还包括两个特殊的方法:构造方法和析构方法,这两个方法都是系统内置方法

9.3.1 构造方法

构造方法指的是 init() 方法

创建对象时系统自动调用,从而实现对象的初始化

每个类默认都有一个 init() 方法,可以在类中显式定义 init() 方法,init() 方法可以分为无参构造方法有参构造方法

当使用无参构造方法创建对象时,所有对象的属性都有相同的初始值,示例:

py 复制代码
class Car:
    def __init__(self): # 无参构造方法
        self.color = 'red'

    def show_color(self):
        print(f"color: {self.color}")

c1 = Car()
c1.show_color()

输出结果如下:

bash 复制代码
color: red

当使用有参构造方法创建对象时,对象的属性可以有不同的初始值,示例:

py 复制代码
class Car:
    def __init__(self, color): # 有参构造方法
        self.color = color

    def show_color(self):
        print(f"color: {self.color}")

c1 = Car("green") # 将 green 传递给 color
c1.show_color()

输出结果如下:

bash 复制代码
color: green

9.3.2 析构方法

析构方法 del()销毁对象时 系统自动调用的方法,每个类默认都有一个 del() 方法,可以显式定义析构方法,示例:

py 复制代码
class Car:
    def __init__(self, color): # 有参构造方法
        self.color = color

    def __del__(self): # 析构方法
        print("Bye!")

    def show_color(self):
        print(f"color: {self.color}")

c1 = Car("green")
c1.show_color()

9.4 封装

封装是面向对象的重要特性之一,它的基本思想是对外隐藏类的细节,提供用于访问类成员的公开接口

如此,类的外部无需知道类的实现细节,只需要使用公开接口便可访问类的内容,这在一定程度上保证了类内数据的安全

为了契合封装思想,我们在定义类时需要满足以下两点要求

  1. 将类属性声明为私有属性
  2. 添加两类供外界调用的公有方法,分别用于设置或获取私有属性的值
py 复制代码
class Person:
    def __init__(self, name):
        self.name = name # 公有属性
        self.__age = 1   # 私有属性

    def set_age(self, new_age):
        if 0 < new_age <= 120:
            self.__age = new_age

    def get_age(self):
        return self.__age

person = Person("Jack")
person.set_age(22)
print(f"name: {person.name}")
print(f"age: {person.get_age()}")

输出结果如下:

py 复制代码
name: Jack
age: 22

9.5 继承

继承是面向对象的重要特性之一,它主要用于描述类与类之间的关系,在不改变原有类的基础上扩展原有类的功能

若类与类之间具有继承关系,被继承的类称为父类或基类,继承其他类的类称为子类或派生类,子类会自动拥有父类的公有成员

9.5.1 单继承

单继承即子类只继承一个父类。现实生活中,波斯猫、折耳猫、短毛猫都属于猫类,它们之间存在的继承关系即为单继承,语法如下:

py 复制代码
class 子类名(父类名):

子类继承父类的同时会自动拥有父类的公有成员,自定义类默认继承基类 object

示例:

py 复制代码
class Square:
    def __init__(self):
        self.a = 3
    def set_a(self, a):
        self.a = a
    def get_area(self):
        return self.a * self.a

class Rectangle(Square):
    pass

r1 = Rectangle()
print(r1.get_area())

输出结果如下:

bash 复制代码
9

9.5.2 多继承

程序中的一个类也可以继承多个类,如此子类具有多个父类,也自动拥有所有父类的公有成员

Python 中多继承的语法格式如下:

py 复制代码
class 子类名(父类名1, 父类名2, ...):

示例:

py 复制代码
class Car:
    def drive(self):
        print("Driving")

class Plane:
    def fly(self):
        print("Flying")

class Deluxo(Car, Plane):
    pass

d1 = Deluxo()
d1.drive()
d1.fly()

输出内容如下:

bash 复制代码
Driving
Flying

!NOTE

如果多继承时出现多个同名方法时,则按照继承顺序优先集成

9.5.3 重写

子类会原封不动地继承父类的方法,但子类有时需要按照自己的需求对继承来的方法进行调整,也就是在子类中重写从父类继承来的方法

在子类中定义与父类方法同名的方法,在方法中按照子类需求重新编写功能代码即可

示例:

py 复制代码
class square:
    def get_shape(self):
        print("square")

class triangle(square):
    def get_shape(self):
        print("triangle")

s1 = square()
s2 = triangle()
s1.get_shape()
s2.get_shape()

输出内容如下:

bash 复制代码
square
triangle

子类重写了父类的方法之后,无法直接访问父类的同名方法,但可以使用 super() 函数间接调用父类中被重写的方法,示例:

py 复制代码
class square:
    def get_shape(self):
        print("square")     # square

class triangle(square):
    def get_shape(self):
        super().get_shape() # square
        print("triangle")   # triangle

s1 = square()
s2 = triangle()
s1.get_shape()
s2.get_shape()

9.6 多态

多态是面向对象的重要特性之一,它的直接表现即让不同类的同一功能可以通过同一个接口调用,表现出不同的行为

示例:

py 复制代码
class Computer:
    def usb1(self, obj):
        obj.set()
    def usb2(self, obj):
        obj.set()

class Mouse:
    def set(self):
        print('Mouse is set')

class Keyboard:
    def set(self):
        print('Mouse is set')

mouse = Mouse()
keyboard = Keyboard()

computer = Computer()
computer.usb1(mouse)
computer.usb1(keyboard)

输出内容如下:

bash 复制代码
Mouse is set
Keyboard is set

10. 异常

10.1 什么是异常

程序开发或运行时可能出现异常,开发人员和运维人员需要辨别程序的异常,明确这些异常是源于程序本身的设计问题,还是由外界环境的变化引起,以便有针对性地处理异常

程序运行出现异常时,若程序中没有设置异常处理功能,解释器会采用系统的默认方式处理异常,即返回异常信息、终止程序

异常信息中通常包含异常代码所在行号 、异常的类型 和异常的描述信息

示例:print(1/0)

bash 复制代码
Traceback (most recent call last):
  File "C:\Users\XXXXX\PycharmProjects\PythonProject\105\test\test.py", line 1, in <module>
    print(1/0)
          ~^~
ZeroDivisionError: division by zero

10.2 异常类型

Python 程序运行出错时产生的每个异常类型都对应一个类,程序运行时出现的异常大多继承自 Exception 类,Exception 类又继承了异常类的基类 BaseException

10.2.1 NameError

NameError 是程序中使用了未定义的变量时会引发的异常

示例:print(a)

bash 复制代码
Traceback (most recent call last):
  File "C:\Users\XXXXX\PycharmProjects\PythonProject\105\test\test.py", line 1, in <module>
    print(a)
          ^
NameError: name 'a' is not defined

10.2.2 IndexError

IndexError 是程序越界访问时会引发的异常

示例:

bash 复制代码
# s = "Hello"
# print(s[100])

Traceback (most recent call last):
  File "C:\Users\XXXXX\PycharmProjects\PythonProject\105\test\test.py", line 2, in <module>
    print(s[100])
          ~^^^^^
IndexError: string index out of range

10.2.3 AttributeError

AttributeError 是使用对象访问不存在的属性时引发的异常

示例:

bash 复制代码
# class Car:
#     wheels = 4
# 
# c1 = Car()
# print(c1.color)

Traceback (most recent call last):
  File "C:\Users\XXXXX\PycharmProjects\PythonProject\105\test\test.py", line 5, in <module>
    print(c1.color)
          ^^^^^^^^
AttributeError: 'Car' object has no attribute 'color'

10.2.4 FileNotFoundError

FileNotFoundError 是未找到指定文件或目录时引发的异常

示例:

bash 复制代码
# f = open("F:\\1.txt","w")

Traceback (most recent call last):
  File "C:\Users\XXXXX\PycharmProjects\PythonProject\105\test\test.py", line 1, in <module>
    f = open("F:\\1.txt","w")
FileNotFoundError: [Errno 2] No such file or directory: 'F:\\1.txt'

10.3 异常捕获

Python 既可以直接通过 try-except 语句实现简单的异常捕获与处理的功能,也可以将 try-except 语句与 elsefinally 子句组合实现更强大的异常捕获与处理的功能

10.3.1 try-except

try-except 语句语法如下:

py 复制代码
try:
    监控代码
except [异常类型 [as error]]
    捕获异常后的处理代码 

示例:

py 复制代码
num1 = int(input("Enter a division: "))
num2 = int(input("Enter another division: "))

try:
    result = num1 / num2
    print(result)
except ZeroDivisionError:
    print("Division by zero!")

输出结果如下:

bash 复制代码
Enter a division: # 3
Enter another division: # 0
Division by zero!

10.3.2 else 字句

else 子句可以与 try-except 语句组合成 try-except-else 结构,若 try 监控的代码没有异常,程序会执行 else 子句后的代码,语法如下:

py 复制代码
try:
    监控代码
except [异常类型 [as error]]
    捕获异常后的处理代码
else:
    未捕获异常后的处理代码

示例:

py 复制代码
num1 = int(input("Enter a division: "))
num2 = int(input("Enter another division: "))

try:
    result = num1 / num2
except ZeroDivisionError:
    print("Division by zero!")
else:
    print(result)

输出结果如下:

bash 复制代码
Enter a division: # 3
Enter another division: # 2
1.5

10.3.3 finally 字句

finally 子句可以和 try-except 一起使用,语法如下:

py 复制代码
try:
    监控代码
except [异常类型 [as error]]
    捕获异常后的处理代码
finally:
    一定执行的代码

示例:

py 复制代码
num1 = int(input("Enter a division: "))
num2 = int(input("Enter another division: "))

try:
    result = num1 / num2
except ZeroDivisionError:
    print("Division by zero!") # 异常输出
else:
    print(result) # 无异常输出
finally:
    print("Bye!") # 有无异常都输出

输出结果如下:

bash 复制代码
# 正常示例
Enter a division: # 3
Enter another division: # 2
1.5
Bye!

# 异常示例
Enter a division: # 3
Enter another division: # 0
Division by zero!
Bye!

10.4 异常抛出

Python 程序中的异常不仅可以自动触发异常,而且还可以由开发人员使用 raiseassert 语句主动抛出异常

10.4.1 raise

使用 raise 语句可以显式地抛出异常,raise 语句的语法如下:

py 复制代码
raise 异常类 # 使用异常类名引发指定的异常
raise 异常类对象 # 使用异常类的对象引发指定的异常
raise # 使用刚出现过的异常重新引发异常

10.4.2 assert

assert 语句又称为断言语句,其语法如下:

py 复制代码
assert 表达式[, 异常信息]
# 表达式不成立时,输出异常信息

示例:

py 复制代码
num1 = int(input("Enter a number: "))
num2 = int(input("Enter another number: "))

assert num2 !=0 , print("Division by zero!")

result = num1 / num2
print("The result is: ", result)

输出结果如下:

bash 复制代码
# 正常
Enter a number: # 3
Enter another number: # 2
The result is: # 1.5

# 异常
Enter a number: # 3
Enter another number: # 0
Traceback (most recent call last):
  File "C:\Users\XXXXX\PycharmProjects\PythonProject\105\test\test.py", line 4, in <module>
    assert num2 !=0 , "Division by zero!"
           ^^^^^^^^
AssertionError: Division by zero!

10.4.3 异常传递

异常(exceptions)是通过栈(stack)传递的。当函数中发生异常,该异常会被抛出(raised),然后

由最内层的函数向外传递,直到被捕获(caught)或者导致程序终止

使用 raise 异常类型s(异常信息) 可以将异常抛出

示例:

py 复制代码
def func_b():
    print('func_b')
    raise ValueError('ERROR') # 抛出异常 ERROR

def func_a():
    print('func_a')
    func_b() # func_b() 的异常会传递给 func_a()

try:
    func_a() # func_b() 传递给 func_a() 的异常会被捕捉
except ValueError as e:
    print(f'Get Error: {e}')

输出结果如下:

bash 复制代码
func_a
func_b
Get Error: ERROR

10.4.4 自定义异常

自定义异常类可以满足开发者对于自定义的特定情况所要抛出异常的需求,自定义异常类需要继承自 Exception 或其子类,类名一般以 Error 为结尾

示例:

py 复制代码
class InvalidAgeError(Exception): # 自定义异常类
    def __init__(self, age):
        self.age = age
        self.message = "Invaild Age (0~100)"

def check_age(age):
    if not (0 < age < 100):
        raise InvalidAgeError(age)
    print(f"Age OK!")

try:
    check_age(int(input("Please input your age: ")))
except InvalidAgeError as e:
    print(f"Error: " + str(e.message))

输出结果如下:

bash 复制代码
# 正常
Please input your age: # 20
Age OK!

# 异常
Please input your age: # 200
Error: Invaild Age (0~100)
相关推荐
诗句藏于尽头43 分钟前
python实战学习记录
python·学习
草莓熊Lotso1 小时前
C++ 二叉搜索树(BST)完全指南:从概念原理、核心操作到底层实现
java·运维·开发语言·c++·人工智能·经验分享·c++进阶
贝锐1 小时前
多设备可视化管理,向日葵屏幕墙如何塑造IT设备管理范式
运维·远程工作
思成不止于此1 小时前
软考中级软件设计师备考指南(二):计算机体系结构与指令系统
笔记·学习·软件设计师
门思科技1 小时前
主流 LoRaWAN 网络服务器深度对比:ThinkLink、TTS、ChirpStack、Loriot 与 Actility 选型指南
运维·服务器·网络
AI松子6661 小时前
PyTorch-混合精度训练(amp)
人工智能·pytorch·python
MDLZH1 小时前
Pytorch性能调优简单总结
人工智能·pytorch·python
程序员爱钓鱼2 小时前
Python 编程实战 · 实用工具与库 — Flask 路由与模板
前端·后端·python
GIS数据转换器2 小时前
基于GIS的智慧旅游调度指挥平台
运维·人工智能·物联网·无人机·旅游·1024程序员节