[Python] 笔记 001

数组和元组

1. 基本概念

列表(List):Python中最常用的可变序列类型,可以存储任意类型的元素,使用方括号 [] 表示。

my_list = [1, 2, 3, "hello", [4, 5]]

列表可以包含任何类型的对象。例如:

mix_list = [3, "string here", 1.0] # 同时包含了 int string 和 float

当然, 一个列表可以包含零个元素:

empty_list = []

元组(Tuple):不可变序列类型,类似于列表,但一旦定义就不能修改,使用圆括号 () 表示。

my_tuple = (1, 2, 3, "world")

Useage of Tuples 元组的使用

  • 避免意外修改

  • 避免修改函数内部的列表,而该列表将在函数外部使用

  • 用于从函数返回多个值

  • 可以用作字典中的键

2. 可变性

列表是可变的:我们可以对列表进行修改,如添加、删除、或更新元素

my_list = [1, 2, 3]
my_list.append(4)  # 添加元素
my_list[1] = 5  # 修改元素

元组是不可变的:元组定义后其内容不能更改

my_tuple = (1, 2, 3)
# my_tuple[1] = 5  # 会报错:元组的元素不可被修改

3. 常用操作

3.1. 列表的创建

var_name = [item1, item2, item3, ...]
# 或者
ingredients = [
    "200g Crunchy Peanut butter",
    "3/4 cup castor sugar",
    "1/4 teaspoon salt",
    "1 egg"
]

3.2. 列表的访问

ingredients = [
    "200g Crunchy Peanut butter",
    "3/4 cup castor sugar",
    "1/4 teaspoon salt",
    "1 egg"
]
print(ingredients[3]) # 输出第3个元素: 1 egg

3.3 列表的编辑

您可以在赋值语句中使用方括号表示法更改列表的元素:

>>> my_list = [123, 2, -34]
>>> my_list[2] = 9999 # 直接修改列表的第2号元素为9999
>>> my_list
[123, 2, 9999]

也可以使用append()在列表末尾添加一个元素

my_list = [1, 2, 3]
my_list.append(4)  # 结果:[1, 2, 3, 4]

也可以使用insert()在指定位置插入一个元素, insert()在列表中的指定位置插入元素,将现有元素向右移动

<list>.insert(index, element)
# list:要在其中插入元素的列表的名称
# index:要插入元素的位置
# element:要插入到列表中的元素
fruits = ['apple', 'banana', 'cherry']
fruits.insert(1, 'orange') # 在1号元素的位置插入'orange'
print(fruits)  # 输出: ['apple', 'orange', 'banana', 'cherry']

除了 append()Python 列表还支持 + 运算符将列表连接在一起

list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]
combined_list = list1 + list2
print(combined_list)  # 输出: [1, 2, 3, 4, 5, 6]
combined_list = list1 + list2 + list3
print(combined_list)  # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]

3.4 Nested Indexing 嵌套索引

# 以这个二维数组为例
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 访问数组
print(matrix[0])  # Output: [1, 2, 3]
print(matrix[1])  # Output: [4, 5, 6]

# 访问数据内容
print(matrix[0][0])  # Output: 1
print(matrix[1][2])  # Output: 6
print(matrix[2][1])  # Output: 8

# 此时, matrix[0] 为 [1, 2, 3], 所以它的的数据类型为list

3.5 List Slices 列表的切片

切片表示法由两个索引组成,用冒号分隔。第一个索引是切片的开头 (含),第二个索引是切片的结尾 (不包括)

例如:

#            0    1    2    3    4    5    6
#           -7   -6   -5   -4   -3   -2   -1
alphabot = ["a", "b", "c", "d", "e", "f", "g"]

print(alphabot[3:5]) # 输出3(包括)到5号(不包括)的元素: ["d", "e"]
print(alphabot[3:]) # 输出3(包括)到结束的元素: ["d", "e", "f", "g"]
print(alphabot[:5]) # 输出开始到5号(不包括)的元素: ["a", "b", "c", "d", "e"]

3.5.1 Negative index 负指数

负索引从列表末尾开始计数

例如:

print(alphabot[-1]) # 输出倒数第1号元素 "g"
print(alphabot[-5]) # 输出倒数第5号元素 "c"

您可以将负索引与切片混合。例如,要获取最后一个元素之前的所有内容

;

3.6 长度和成员检测

List 和 Tuples 都可以使用 len() 获取长度,也可以使用 in 关键字来检查元素是否存在。

len(my_list)  # 输出:5
2 in my_list  # 输出:True

3.7 Min, Max, Range 最小值、最大值、范围

可以使用min() 函数找到最小值

min(value1, value2, value3, ...)

float 和 int 数据类型的混合(该函数直接比较数值)

str 数据类型min() 函数在字典中查找字符串值在字典中排在前面(如字典顺序)的元素,而不考虑 str 的长度

例如:

small = min(3, 8, 5.3, 2, 7.2, 3)
print(small) # 输出 2

first = min("Python", "INFO1110", 'Coding Exercises', "Language")
print(first) # 输出 Coding Exercises

可以使用max() 函数找到最大值

max(value1, value2, value3, ...)

float 和 int 数据类型的混合(该函数直接比较数值)

str 数据类型 函数在字典中查找字符串值在字典中排在后面(如字典顺序)的元素,而不考虑 str 的长度

例如:

largest = max(3, 8, 5.3, 2, 7.2, 3)
print(largest) # 输出 8

last = max("Python", "INFO1110", 'Coding Exercises', "Language")
print(last) # 输出 Python

# List of numerical values
num_ls = [3, 8, 5.3, 2, 7.2, 3]
max_num = max(num_ls)
print(max_num) # 输出 8

可以使用range() 函数生成给定范围内的数字序列

range(start, stop, step)

start (可选):指定序列的起始编号。此值只能为 int 数据类型。如果未指定 start,则 sequence 将默认从 0 开始

step (可选):指定序列中连续数字之间的差异。负值 step 将返回递减序列 (decrement) 。相反,正值 step 将返回递增序列 (increment)。该步骤只能采用 int 数据类型。如果未指定 step,则默认情况下,两个连续数字之间的差值设置为 1,从而产生增量为 1 的序列

stop (必需):指定序列的停止位置 (不包括)。换句话说,序列将包括所有数字,但不包括 stop。stop 的值只能是 int 数据类型

sequence = range(10)
for i in sequence:
    print(i, end = " ")
# 输出 0 1 2 3 4 5 6 7 8 9
# 程序生成一个连续的序列(即默认为 step = 1),从 0(默认)开始,到 9(包括 9)停止

sequence = range(7, 15)
for i in sequence:
    print(i, end = " ")
# 输出 7 8 9 10 11 12 13 14
# 程序生成一个从 7 开始到 14 (含)停止的序列,两个连续数字之间相差 1 (默认情况下)

sequence = range(2, 10, 2)
for i in sequence:
    print(i, end = " ")
# 输出 2 4 6 8
# 该程序生成一个从 2 开始到 10 结束(不包括)的偶数序列,两个连续数字之间相差 2

sequence = range(10, 0, -1)
for i in sequence:
    print(i, end = " ")
# 输出 10 9 8 7 6 5 4 3 2 1
# 程序生成一个从 10 开始到 1(含)停止的序列,两个连续数字之间相差 -1。这意味着序列按降序排列

4. 转换

列表与元组之间可以相互转换:

my_list = [1, 2, 3]
my_tuple = tuple(my_list)  # 转换为元组
new_list = list(my_tuple)  # 转换为列表

5. 特殊特性

  • 元组的不可变性使得它可以作为字典的键,而列表由于可变性不允许作为字典键

  • 元组的解包:元组常用于解包(unpacking)操作,方便多个变量的赋值

a, b, c = (1, 2, 3)
print(a, b, c)  # 输出:1 2 3

元组解包的概念:元组解包是指将元组中的多个值拆开,并分别赋值给多个变量的过程。元组解包使得在代码中可以轻松地将一组值同时赋值给多个变量,提高了代码的简洁性和可读性。元组解包也可以用于函数返回多个值的场景

# 将元组解包到多个变量中
my_tuple = (10, 20, 30)
a, b, c = my_tuple
print(a, b, c)  # 输出:10 20 30

t = (1, 2, 3, 4, 5)
a, b, c, _, _ = t  # 忽略后两个元素
print(a, b, c)  # 输出: 1 2 3
# 只关心前三个元素,剩下的可以忽略,使用占位符 _

t = (1, 2, 3, 4, 5)
a, b, c, *rest = t  # 将前三个元素解包,剩下的用 rest 收集
print(a, b, c)  # 输出: 1 2 3
print(rest)     # 输出: [4, 5]
# 将剩下的元素保留到另一个变量,可以使用 * 来收集剩下的部分

命令行参数

当程序运行时,可以向程序提供命令行参数

  • sys: 表示 Python 的 sys 模块, 它提供与 Python 解释器和操作系统进行交互的功能

  • argv: 来自 argument vector, 表示命令行参数的向量(或列表)

在 Python 程序中,这些参数以字符串列表的形式传递. 您可以使用 sys.argv 访问它们:

# program.py
import sys
print("First arg:", sys.argv[0])
print("Second arg:", sys.argv[1])
print("Full list:", sys.argv)

如果我们使用以下命令

$ python3 program.py hello there "general kenobi"

我们会得到以下输出

First arg: program.py # 第一个参数, 为python文件的名称
Second arg: hello     # 第二个参数, 为python文件后的第一个参数
Full list: ['program.py', 'hello', 'there', 'general kenobi'] # 使用sys.argv会获取所有的参数的列表, 包括文件名

字典

1. 创建和使用字典

d = {'a': 1, 'b': 2, 'c': 3}
# 'a', 'b', 和 'c' 是字典的键
# 1, 2, 和 3 是字典的值
# 'a': 1 是一个元素,'b': 2 是另一个元素,依此类推
# d = {'a': 1, 'b': 2, 'c': 3} 整体就是一个字典或表

在上面的示例中,“Bob” 是字典 height 中的键,值 188 存储在该键处。您还可以使用变量来访问值

person = "Bob"
if height[person] > 200:
    print("Play basketball?")
# height[person] 这里为188

键必须是不可变对象。您不能将列表用作键,但可以使用 Tuples

newdict = { key1: value1, key2: value2, ...}
newdict = { "name": "Bob", "height": 188 }

可以使用以下方法来初始化字典

d = {}
d = {'a': 1, 'b': 2, 'c': 3}
# 使用大括号 {} 初始化字典
d = dict()
d = dict(a=1, b=2, c=3)
# 使用 dict() 函数初始化字典
d = dict([('a', 1), ('b', 2), ('c', 3)])
# 使用 dict() 函数和列表/元组对初始化字典
d = dict.fromkeys(['a', 'b', 'c'], 0)
# 使用 dict.fromkeys() 初始化字典
# dict.fromkeys() 方法用于创建一个新字典,指定的键使用列表(或任何可迭代对象),所有键的值都被初始化为同一个值(此例中为 0)

错误的初始化方法

d = {'a' = 1, 'b' = 2, 'c' = 3}
# 应使用冒号而不是等号
d = {[1, 2]: 3, 'b': 2}
# 键不能是可变对象
d = { {'a': 1}: 'value' }
# 字典是可变对象,不能作为另一个字典的键

2. 操作

.keys() 方法返回字典中的键列表

.values() 方法返回存储在字典中的值列表

.items()方法返回一个元组列表,每个元组包含一个键及其相应的值

newdict = { "name": "Bob", "height": 188 }
print(list(newdict)) # 输出 ['name', 'height'] 直接将字典的键转换为列表
print(newdict.keys()) # 输出 dict_keys(['name', 'height'])
print(newdict.values()) # 输出 dict_values(['Bob', 188])
print(newdict.items()) # 输出 dict_items([('name', 'Bob'), ('height', 188)])

可以使用使用 in 运算符检查字典中是否存在键

if "Bob" in newdict:
    print("We found bob!")
if "Tom" not in newdict:"
    print("We cannot find Tom")

如果键存在,则 .get(key, default_value) 方法可以检索值。如果 key 不存在,则返回默认值

height # 为 {'Bob': 188}
height.get('Bob', 170) # 输出 188, The stored value is retrieved.
height.get('Tom', 170) # 输出 170, The default value is used.

您可以使用 for 循环遍历字典的所有键和值

for key, val in newdict.items():
    print("key is ", key, "value is ", val)
# 输出 
# key is name value is Bob
# key is height value is 188

我们可以通过指定新键并添加关联值来添加到字典中

首先, 我们使用 {} 初始化空字典

balls = {}

我们可以通过指定新键并添加关联值来添加到字典中

balls['Red'] = 5
print('Number of red balls is:', balls['Red'])

或者使用for来遍历

balls = {}
balls['Red'] = 5
balls['Green'] = 3
balls['Blue'] = 1

# iterate through the keys in the dictionary
for key in balls:
    print(f'Colour: {key}, Num: {balls[key]}')

# 输出
# Colour: Red, Num: 5
# Colour: Green, Num: 3
# Colour: Blue, Num: 1

键是唯一的,设置两次只会替换值

balls = {}
balls['Red'] = 5
balls['Red'] = 9
print(balls['Red'])
# 输出 9

就像列表一样,我们也可以从具有值的字典开始,它并不总是需要以空开头

balls = {'Red': 5, 'Blue': 3, 'Green': 1}
for key in balls:
    print(f'{key}: {balls[key]}')

# 输出
# Colour: Red, Num: 5
# Colour: Green, Num: 3
# Colour: Blue, Num: 1

# 你提到的代码确实修改了键 'Red' 对应的值,但它并没有改变键本身的不可变特性,而是替换了键对应的值。在这种情况下,键 'Red' 仍然是不可变的字符串,字典的键没有被修改,而是字典中这个键对应的值发生了变化

Mutable and Immutable Data 可变和不可变数据

1. 定义

定义:不可变数据类型在创建后无法更改

不可变对象的例子:

  • 字符串(str):不能修改它的内容。

  • 整数(int):整数的值不能改变。

  • 浮点数(float):浮点数的值不能改变。

  • 元组(tuple):元组中的元素不能修改。

相对的,像列表(list)和字典(dict)这样的对象是可变的,它们的内容是可以更改的

为什么键具有不可变性但能被“更改”?

这里的“更改”不是指修改键的内容,而是更新字典中键对应的值。具体来说:

  • 字典中的键是不可变的,即一旦某个键被插入字典,其内容就不能改变。但你可以更新该键所对应的值,甚至可以删除该键,然后插入一个新的键值对。

d = {'a': 1}

# 更新键 'a' 对应的值
d['a'] = 2
print(d)  # 输出: {'a': 2}

# 尝试修改键 'a' 本身是不可能的

字符串(str)的不可变性

s = "hello"
# 尝试修改字符串中的一个字符
s[0] = "H"  # 试图修改第一个字符
# 输出 TypeError: 'str' object does not support item assignment

正确的操作是创建一个新的字符串,比如通过字符串拼接

s = "hello"
s = "H" + s[1:]
print(s)  # 输出: "Hello"
# 创建了一个新字符串对象并重新赋值给 s

同样, 整数(int)的不可变性

x = 10
# 尝试修改整数的某部分(不可能直接修改)
x += 5  
# 实际上创建了一个新的整数对象并重新赋值给 x
print(x)  # 输出: 15

浮点数(float)的不可变性

y = 3.14
# 尝试修改浮点数的值
y += 1.0  
# 创建了一个新的浮点数对象并重新赋值给 y
print(y)  # 输出: 4.14

副作用, 不正确使用可变数据类型可能会导致意外的副作用,从而导致程序中出现错误

x = [1, 2, 3]   # 创建一个列表 [1, 2, 3],并将变量 x 指向它
y = x           # 将 y 也指向与 x 相同的列表对象
x[0] = 99       # 修改列表中的第一个元素,x[0] = 99
print(f"{x=}, {y=}") # 输出 x=[99, 2, 3], y=[99, 2, 3]

在这里,x 和 y 都是对同一个列表对象的引用。因此当你修改 x[0] = 99 时,实际上是修改了那个列表对象的内容,而不是变量 x 本身。所以,y 也会显示相同的结果,因为 y 仍然指向同一个列表

x = [1, 2, 3]
y = x
print(id(x))  # 输出 x 的内存地址
print(id(y))  # 输出 y 的内存地址

你会发现 id(x) 和 id(y) 是相同的,这说明 x 和 y 指向的是同一个对象

x = [1, 2, 3]
y = x[:]      # 使用切片创建 x 的一个副本
x[0] = 99
print(f"{x=}, {y=}")
# 输出 x=[99, 2, 3], y=[1, 2, 3]

或者使用y = list(x)

这行代码创建了 x 的一个浅拷贝,y 将是一个全新的列表对象,内容与 x 在创建时相同,但它们是两个不同的对象

x = [1, 2, 3]
y = list(x)  # 使用 list() 创建 x 的一个浅拷贝
x[0] = 99
print(f"{x=}, {y=}")
# 输出 x=[99, 2, 3], y=[1, 2, 3]

浅拷贝的含义:如果 x 和 y 中的元素是不可变对象(如整数、字符串),拷贝是安全的;但如果它们包含可变对象(如列表或字典),浅拷贝只会复制它们的引用,修改这些可变对象的内容会影响两个列表

浅拷贝 vs 深拷贝:

  • 浅拷贝:使用 list(x) 或 x[:]或x = x.copy()只拷贝列表的第一层元素。如果列表中的元素是可变对象,那么修改这些可变对象的内容会影响到原列表和拷贝。

  • 深拷贝:使用 copy.deepcopy(),会递归地拷贝所有嵌套的可变对象,确保拷贝的对象完全独立于原对象。

如果 a 和 b 是可变对象,那么对 b 的修改可能会影响到 a

如果 a 和 b 是不可变对象,那么对 b 的修改不会影响到 a

例如:

a = 1
b = a

b = 5
print('a:', a)
print('b:', b)

# 输出
# a: 1
# b: 5
a = [1, 2, 3]  # a 是一个可变对象(列表)
b = a          # b 指向与 a 相同的列表对象

b[0] = 99      # 修改 b 中的第一个元素
print('a:', a) # a 也会反映出修改后的值
print('b:', b)

# 输出
# a: [99, 2, 3]
# b: [99, 2, 3]
def fun(z):
    z.pop()
    return True

x = [3,2,1]
fun(x)
print(x)
# 输出 [3, 2]

x = [3,2,1]
x.pop(1)
print(x)
# 输出 [3, 1] 删除了1号元素
def fun(z):
    z = list(z)  # 使用 list(z) 代替 z.copy()
    z.pop()      # 修改 z 的副本,移除最后一个元素
    return True

x = [3, 2, 1]
fun(x)
print(x)  # 输出仍然是 [3, 2, 1],x 不受影响
# 这里 z = z.copy() 可以换成 z = list(z),两者的效果在这个场景下是相同的:它们都创建了原列表的浅拷贝

For 循环

for var in iterable:
    ...

for 循环可以迭代任何可迭代对象, 列表、字符串和字典等数据结构可以迭代。一次取出一个元素,存储在变量 var 中,并进行处理

for x in [7, 3, 6, 5]:
    print(x)
# 依次取出 7, 3, 6, 5
# 输出
7
3
6
5

for char in "Hello":
    print(char)
# 依次取出"Hello" 中的每个字符
# 输出:
H
e
l
l
o

with open("myfile") as file:
    for line in file:
        print(line)
# 假设文件 "myfile" 中的内容是:
Hello, World!
This is a test file.
# 输出:
Hello, World!

This is a test file.

使用range()

range() 函数提供整数序列。range() 的一般格式为

range()的具体使用方法

range(start, end, step
  • start:起始编号(默认值为 0)。

  • end:停止编号(不包括在序列中)。

  • step:增量(默认值为 1)。

for num in range(4):
    print(num)
# 输出:
0
1
2
3

检查数据类型

1. 检查 string

可以使用str.isalpha检查是否是string数据类型

如果字符串中的所有字符都是字母格式的,并且至少有一个字符,则返回 True,否则返回False

word1 = "x"
word2 = "A"
word3 = "啊"
word4 = "-"
word5 = "1"
word6 = "114514"
word7 = "114514ok"
print(word1.isalpha())
print(word2.isalpha())
print(word3.isalpha())
print(word4.isalpha())
print(word5.isalpha())
print(word6.isalpha())
print(word7.isalpha())

# 输出为:
True
True
True
False
False
False
False

2. 检查 int

可以使用int.isdigit检查是否是int数据类型

如果字符串中的所有字符都是数字并且至少有一个字符,则返回 True,否则返回 False

word1 = "x"
word2 = "0"
word3 = "3"
word4 = "-"
print(word1.isdigit())
print(word2.isdigit())
print(word3.isdigit())
print(word4.isdigit())

处理错误

1. Syntax Errors 语法错误

语法错误,也称为解析错误,可能是您在学习 Python 时收到的最常见的投诉类型。当 Python 无法解析您的代码时,就会出现这些错误,这意味着它不会运行您的程序。你可以把它看作是用它不熟悉的语言说话。如果 Python 不理解你,它就不会运行它。Python 会通过引发 3 个异常中的 1 个来告知你它遇到了语法错误

  • SyntaxError
    语法错误

  • IndentationError
    IndentationError (缩进错误)

  • TabError
    TabError 错误

语法不正确,例如尝试分配表达式

length = 5.0
width = 2.5

# correct assignment: area = length * width
length * width = area
# 报错:
  File "/home/main.py", line 5
    length * width = area 
    ^^^^^^^^^^^^^^
SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?

遗漏重要字符,例如缺少冒号、引号、括号

age = 20

# missing the :
if age >= 20
    print('You are an adult!')
# 报错:
  File "/home/main.py", line 4
    if age >= 20
                ^
SyntaxError: expected ':'

缩进不正确

colours = ['Red', 'Green', 'Blue']

for colour in colours:
# forgetting to indent the print
print(colour)
# 报错:
  File "/home/main.py", line 5
    print(colour)
    ^
IndentationError: expected an indented block after 'for' statement on line 3

2. Runtime Errors 运行时错误

2.1 TypeError 类型错误

例如, 不能讲str类型和int/float类型相加

print("Adding a string and integer...")
result = '10' + 10

# 报错:
Adding a string and integer...
Traceback (most recent call last):
  File "/home/main.py", line 2, in <module>
    result = '10' + 10
             ~~~~~^~~~
TypeError: can only concatenate str (not "int") to str

2.2 ZeroDivisionError 零整除错误

当除法或模数 (%) 运算的第二个参数为零时引发

1 / 0

# 报错:
Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    1 / 0
    ~~^~~
ZeroDivisionError: division by zero

2.3 NameError 名称错误

找不到名称时引发, 变量没有定义 当您在代码中定义的变量名称拼写错误时,您可能会遇到这种情况

span = 5
spam * 3

# 报错:
Traceback (most recent call last):
  File "/home/main.py", line 2, in <module>
    spam * 3
    ^^^^
NameError: name 'spam' is not defined. Did you mean: 'span'?

2.4 ValueError

当操作或函数收到具有正确类型但值不适当的参数时引发。一个常见的例子是将字符串传递给 int() 函数,而字符串值本身是不合适的

int('Hello!')

# 报错:
Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    int('Hello!')
ValueError: invalid literal for int() with base 10: 'Hello!'

3. Handling Runtime Errors 处理运行时错误

3.1 捕获错误

我们可以使用 try 和 except 来捕获异常

try:
    y = 1
    z = 0
    x = y / z
except:
    print(f"an error occurred, y was {y}, z was {z}")

您还可以使用 raise 语句显式引发异常

while True:
    what = input("What? ")
    if what == "QUIT":
        raise RuntimeError("QUITTING THE PROGRAM!")
    print("OK, ", what)

此循环将继续运行,直到用户进入 QUIT。用户输入 QUIT 后,将引发 RuntimeError 异常,并显示错误消息 “QUITTING THE PROGRAM!”。这将中断程序执行,并因此终止我们的程序

3.2 获取有关错误的信息

要获取有关错误的详细信息,您可以使用 except Exception as e:语句以捕获异常对象

try:
    y = 1
    z = 0
    x = y / z
except Exception as e:
    print(f"A exception have occured, details: {e}")
# 在此示例中,异常的详细信息存储在变量 e 中,可以打印出该变量以查看出了什么问题
# 输出:
A exception have occured, details: division by zero

3.3 指定异常

x = 1
y = 0
try:
    result = x / y
except ZeroDivisionError:
    print('Cannot divide by zero!')

# 输出:
Cannot divide by zero!
try:
    number = int(input('Enter a number: '))
except ValueError:
    print(f'{number} was not a number!')

# 只有用户输入数字时,才会定义数字。如果用户未输入 number,则语句 number = int(input('Enter a number: ')) 将失败并引发异常,因此永远不会为 number 分配值
# 如果输入非数字, 则整个程序会报错:
Traceback (most recent call last):
  File "/home/main.py", line 2, in <module>
    number = int(input('Enter a number: '))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'f'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/main.py", line 4, in <module>
    print(f'{number} was not a number!')
             ^^^^^^
NameError: name 'number' is not defined
# 修正后的程序
try:
    number = input('Enter a number: ')
    number = int(number)
except ValueError:
    print(f'{number} was not a number!')

# 输出:
Enter a number: g
g was not a number!

3.3.1 指定多个异常

try:
    <statement(s)>
except <exception>:
    <statement(s)>
except <exception>:
    <statement(s)>
except <exception>:
    <statement(s)>

如果在 try 块内引发异常,它将自上而下检查是否有任何 except 语句正在捕获引发的异常。例如,如果第一个 except 语句没有处理引发的异常,它将检查第二个 except 语句,依此类推,直到找到正在捕获其异常的 except 语句

例如:

try:
    number = input("Dividing 42 by... ")
    number = int(number)
    result = 42 / number
    print(f"42/{number} = {result}")
except ValueError:
    print(f"Hey, '{number}' is not a number!")
except ZeroDivisionError:
    print("Cannot divide by zero!")

# 首先处理ValueError, 如果不存在ValueError, 则处理ZeroDivisionError

Python 函数

函数允许您在程序的不同部分多次重用代码

要定义函数,请使用 def 关键字, 例如:

def convert(miles, gallons):
    km = miles * 1.60934
    litres = gallons * 3.78541
    print('Hello')
    return round(litres * 100 / km, 1)
  • def:指示函数定义的开始。

  • convert:函数的名称(必须遵循与变量名称相同的规则)。

  • miles, gallons:函数的参数,它们是函数的输入。

  • return:指定函数将生成的值, 不必须, 默认为None

print(convert(30, 1))

# 输出:
7.8

(convert(30, 1))

# 输出:
Hello
7.8

当尝试在 my_special_add(x, y) 函数的范围之外打印 x 的值时,程序会引发 NameError 异常。这是因为 x 是一个参数,只能在 my_special_add(x, y) 函数的范围内访问, 在函数外部声明的变量可以在函数范围内被覆盖

def my_special_add(x, y):
    return x + y

print(x)

# 报错:
Traceback (most recent call last):
  File "/home/main.py", line 4, in <module>
    print(x)
          ^
NameError: name 'x' is not defined
def get_starblock(n):
    return '*****\n' * n

num = 4
print(get_starblock(num))

# 输出:
*****
*****
*****
*****

输入和输出

您可以打开文件进行读取或写入

f = open("filename")
  • .readline(): Returns a single string, one line from the file.
    .readline():返回单个字符串,即文件中的一行。

  • .readlines(): Returns a list of strings, each string is one line from the file.
    .readlines():返回字符串列表,每个字符串是文件中的一行。

  • .read(n): Returns n bytes of data. If used without any parameter, it returns the entire file content.
    .read(n):返回 n 字节的数据。如果在没有任何参数的情况下使用,则返回整个文件内容。

  • .write(byte_string): Writes the string into the file. Unlike print, this does not append a newline at the end.
    .write(byte_string):将字符串写入文件。与 print 不同,这不会在末尾附加换行符。

open 函数有一个额外的参数,用于指定打开文件的模式:

  • "r": Read mode (default).
    “r”:读取模式(默认)。

  • "w": Write mode (creates a new file or truncates an existing file).
    “w”:写入模式(创建新文件或截断现有文件)。

  • "a": Append mode (writes data to the end of the file).
    “a”:附加模式(将数据写入文件末尾)。

当使用写入 (“w”) 或附加 (“a”) 模式时,如果文件尚不存在,则会自动创建该文件

Closing a file 关闭文件

请记住,在完成对文件对象的任何操作时,始终要关闭该文件对象。

这是因为在使用完文件对象后不关闭它可能会导致不需要的行为,例如:

  • Memory leak 内存泄漏

  • Modified version of the files might not be saved
    可能无法保存文件的修改版本

处理 FileNotFoundError 异常

f_obj = open("animals.txt", "r")
f_obj.close()

如果文件不存在, 会抛出异常

Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    f_obj = open("animals.txt", "r")
            ^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'animals.txt'

我们可以使用 tryexcept 块,如处理错误 (Essentials) 中所述,以处理此异常和/或很好地退出程序

try:
    f_obj = open("animals.txt", "r")
    
except FileNotFoundError:
    print("Can't open non-existent file!")

字符串方法:split()和 strip()

split() 方法根据指定的分隔符将字符串划分为子字符串列表

<string>.split(separator) 
  • <string> (Required): A string to be split.
    <string> (必需):要拆分的字符串。

  • separator (Optional): The characters used to divide the string. If omitted, any whitespace characters are used.
    separator (可选):用于划分字符串的字符。如果省略,则使用任何空白字符。

original_str = "Hello everyone, Welcome     to INFO1110!"
split_str = original_str.split()
print(split_str)

# 输出:
['Hello', 'everyone,', 'Welcome', 'to', 'INFO1110!']
original_str = "Hello, Hello, Hello!  Welcome to INFO1110!"
split_str = original_str.split(",")
print(split_str)

# 输出:
['Hello', ' Hello', ' Hello!  Welcome to INFO1110!']

str.strip() 方法

默认情况下,strip() 方法从字符串中删除前导和尾随空格字符

<string>.strip(characters)
  • <string> (Required): A string to be stripped.
    <string> (必需):要剥离的字符串。

  • characters (Optional): A set of characters to remove from the beginning and end of the <string>. If omitted, whitespace characters are removed.
    字符(可选):要从 <string> 的开头和结尾删除的一组字符。如果省略,则删除空白字符。

original_str = "      Hello everyone, Welcome to INFO1110!     "
strip_str = original_str.strip()
print(strip_str)
print(f"Length of the original string: {len(original_str)}")
print(f"Length of the string after performing strip(): {len(strip_str)}")

# 输出:
Hello everyone, Welcome to INFO1110!
Length of the original string: 47
Length of the string after performing strip(): 36
original_str = "....,....,/Hello, Hello, Hello!  Welcome to INFO1110!@@,.@..,"
strip_str = original_str.strip(",.")
print(strip_str)

# 输出:
/Hello, Hello, Hello!  Welcome to INFO1110!@@,.@

strip() 只会从字符串的开头和结尾删除指定字符,不会删除字符串中间的字符

replace() 方法

replace() 是字符串方法,用于替换字符串中的指定部分。它的语法如下

str.replace(old, new, count)

参数说明:

  • old:要替换的目标字符串。

  • new:用于替换 old 的新字符串。

  • count(可选):指定要替换的次数。如果不指定,默认会替换所有匹配的 old

例如:

text = "Hello World! World is beautiful."
new_text = text.replace("World", "Earth")
print(new_text)

# 输出:
Hello Earth! Earth is beautiful.


[Python] 笔记 001
http://localhost:8090/archives/pybj1
作者
Gzcheng
发布于
2024年10月07日
更新于
2024年10月27日
许可协议