- 2025-03-01
-
发表了主题帖:
《Python编程:从入门到实践(第3版)》读书笔记6:用户输入和while循环
本帖最后由 逝逝逝 于 2025-3-4 23:34 编辑
第7章 用户输入和while循环
7.1 input()函数的工作原理
在 Python 中,‘input()’ 函数用于从标准输入(通常是键盘)读取用户输入,并将输入内容以字符串形式返回。
1. 基本工作原理
程序暂停:当执行到 ’input()`‘时,程序会暂停,等待用户输入。
输入确认:用户输入后需按 回车键(Enter),输入内容会被读取。
返回值:输入的文本会作为字符串返回(不包含末尾的换行符)。
示例
name = input("请输入你的名字:") # 显示提示信息并等待输入
print(f"你好,{name}!")
2. 输入内容处理
始终返回字符串:无论输入数字、符号还是文本,’input()‘ 均返回字符串。
类型转换:需手动转换数据类型(如 ‘int()’、‘float()’、‘list()’ 等)。
示例
age = input("请输入年龄:")
age_int = int(age) # 转为整数(若输入非数字会报错)
3. 安全输入与错误处理
验证输入格式:防止类型转换错误(如用户输入非数字时转’int‘会崩溃)。
使用’try-except‘捕获异常
示例
while True:
try:
num = int(input("请输入整数:"))
break
except ValueError:
print("输入无效,请重新输入!")
练习 7.1 汽车租赁
编写一个程序,询问用户要租什么样的汽车,并打印一条消息,如下所示。
Let me see if I can find you a Subaru
car = input("What kind of car would you like? ")
print(f"Let me see if I can find you a {car.title()}.")
运行结果:
What kind of car would you like? audi
Let me see if I can find you a Audi.
练习 7.2 餐馆订位
编写一个程序,询问用户有多少人用餐。如果超过8个人,就打印一条消息,指出没有空桌;否则指出有空桌。
party_size = input("How many people are in your dinner party tonight? ")
party_size = int(party_size)
if party_size > 8:
print("I'm sorry, you'll have to wait for a table.")
else:
print("Your table is ready.")
运行结果:
How many people are in your dinner party tonight? 7
Your table is ready.
How many people are in your dinner party tonight? 12
I'm sorry, you'll have to wait for a table.
练习 7.3 10 的整数倍
让用户输入一个数,并指出这个数是否是 10 的整数倍。
number = input("input a number:")
number = int(number)
if number % 10 == 0:
print(f"{number} is a multiple of 10.")
else:
print(f"{number} is not a multiple of 10.")
运行结果:
input a number:20
20 is a multiple of 10.
input a number:12
12 is not a multiple of 10.
7.2 while循环
在 Python 中,‘while’ 循环用于重复执行代码块,直到条件不再满足。
基本语法
while 条件:
# 循环体代码
else:
# 循环正常结束后执行(非 break 退出时触发)
示例
count = 0
while count < 5:
print(f"当前计数: {count}")
count += 1
else:
print("循环正常结束")
运行结果
当前计数: 0
当前计数: 1
当前计数: 2
当前计数: 3
当前计数: 4
循环正常结束
核心特点
条件驱动:只要条件为 ’True‘,循环持续执行。
灵活性:适用于不确定循环次数的场景(如用户输入验证、实时监控)。
手动控制:需在循环体内更新条件变量,避免无限循环。
常见应用场景
(1) 用户输入验证
while True:
user_input = input("请输入 'yes' 退出:")
if user_input.lower() == "yes":
break
print("输入无效,请重试!")
(2) 处理动态数据
data = [1, 2, 3, 4, 5]
while data:
item = data.pop()
print(f"处理元素: {item}")
‘break’和‘continue’
num = 0
while num < 10:
num += 1
if num == 3:
continue # 跳过本次循环剩余代码
if num == 7:
break # 退出循环
print(num)
# 输出: 1 2 4 5 6
避免无限循环
# 条件变量未更新
count = 0
while count < 5:
print("卡在循环中!") # count 始终为 0
正确写法
count = 0
while count < 5:
print("正常执行")
count += 1 # 必须更新条件变量
性能优化技巧:使用标志变量,简化复杂退出条件
running = True
while running:
if error_occurred:
running = False
练习 7.4 比萨配料
编写一个循环,提示用户输入一系列比萨配料,并在用户输入'quit'时结束循环。每当用户输入一种配料后,都打印一条消息,指出要在比萨中添加这种配料。
prompt = "\nWhat topping would you like on your pizza?"
prompt += "\nEnter 'quit' when you are finished: "
while True:
topping = input(prompt)
if topping != 'quit':
print(f" I'll add {topping} to your pizza.")
else:
break
运行结果:
What topping would you like on your pizza?
Enter 'quit' when you are finished: 2
I'll add 2 to your pizza.
What topping would you like on your pizza?
Enter 'quit' when you are finished: QUIT
I'll add QUIT to your pizza.
What topping would you like on your pizza?
Enter 'quit' when you are finished: quit
练习 7.5 电影票
有家电影院根据观众的年龄收取不同的票价:不到3岁的观众免费;3(含)~12岁的观众收费10美元;年满12岁的观众收费15美元。请编写一个循环,在其中询问用户的年龄,并指出
其票价。
prompt = "\nHow old are you?"
prompt += "\nEnter 'quit' when you are finished. "
while True:
age = input(prompt)
if age == 'quit':
break
age = int(age)
if age < 3:
print(" You get in free!")
elif age < 12:
print(" Your ticket is $10.")
else:
print(" Your ticket is $15.")
运行结果:
How old are you?
Enter 'quit' when you are finished. 12
Your ticket is $15.
How old are you?
Enter 'quit' when you are finished. 4
Your ticket is $10.
How old are you?
Enter 'quit' when you are finished. 0
You get in free!
How old are you?
Enter 'quit' when you are finished. quit
7.3 使用while循环处理列表和字典
在 Python 中,`while` 循环可以灵活处理列表和字典,尤其适用于需要动态修改容器内容或条件复杂的场景。
1. 处理列表
(1) 遍历列表
fruits = ["apple", "banana", "cherry"]
index = 0
while index < len(fruits):
print(fruits[index])
index += 1
# 输出: apple banana cherry
(2) 动态修改列表
# 删除所有偶数
numbers = [1, 2, 3, 4, 5, 6]
i = 0
while i < len(numbers):
if numbers[i] % 2 == 0:
del numbers[i] # 删除元素后,后续元素前移,索引不需递增
else:
i += 1 # 未删除时递增索引
print(numbers) # 输出: [1, 3, 5]
(3) 条件筛选
# 从后向前遍历(避免索引错位)
data = [10, 20, 30, 40, 50]
i = len(data) - 1
while i >= 0:
if data[i] > 25:
data[i] = data[i] * 2
i -= 1
print(data) # 输出: [10, 20, 60, 80, 100]
2. 处理字典
(1) 遍历字典键
person = {"name": "Alice", "age": 30, "city": "New York"}
keys = list(person.keys()) # 转换为列表避免遍历时修改错误
index = 0
while index < len(keys):
key = keys[index]
print(f"{key}: {person[key]}")
index += 1
# 输出: name: Alice \n age:30 \n city:New York
(2) 动态删除键值对
# 删除值为空的键
user_data = {"name": "Bob", "email": "", "age": 25}
keys = list(user_data.keys()) # 先固定键列表
index = 0
while index < len(keys):
key = keys[index]
if not user_data[key]: # 值为空则删除
del user_data[key]
index += 1
print(user_data) # 输出: {'name': 'Bob', 'age': 25}
(3) 条件更新字典
# 将所有数值类型的值翻倍
data = {"a": 10, "b": "hello", "c": 3.14, "d": [1, 2]}
keys = list(data.keys())
index = 0
while index < len(keys):
key = keys[index]
if isinstance(data[key], (int, float)):
data[key] *= 2
index += 1
print(data) # 输出: {'a':20, 'b':'hello', 'c':6.28, 'd':[1,2]}
练习 7.8 熟食店
创建一个名为sandwich_orders的列表,其中包含各种三明治的名字,再创建一个名为finished_sandwiches的空列表。遍历列表sandwich_orders,对于其中的每种三明治,都打印一条消息,如“I made your tuna sandwich.”,并将其移到列表finished_sandwiches中。当所有三明治都制作好后,打印一条消息,将这些三明治列出来。
sandwich_orders = ['a','b','c']
finished_sandwiches = []
while sandwich_orders:
sandwich = sandwich_orders.pop()
finished_sandwiches.append(sandwich)
print(f'I made your {sandwich} sandwich')
print("\n")
for sandwich in finished_sandwiches:
print(f"I made a {sandwich} sandwich.")
运行结果
I made your c sandwich
I made your b sandwich
I made your a sandwich
I made a c sandwich.
I made a b sandwich.
I made a a sandwich.
练习 7.9 五香烟熏牛肉卖完了
使用为练习7.8创建的列表sandwich_orders,并确保'pastrami'在其中至少出现了三次。在程序开头附近添加这样的代码:先打印一条消息,指出熟食店的五香烟熏牛肉(pastrami)卖完了;再使用一个while循环将列表sandwich_orders 中的'pastrami'都删除。确认最终的列表finished_sandwiches中未包含'pastrami'。
sandwich_orders = ['a','b','c','pastrami','pastrami','pastrami']
finished_sandwiches = []
print("I'm sorry, we're all out of pastrami today.")
while 'pastrami' in sandwich_orders:
sandwich_orders.remove('pastrami')
while sandwich_orders:
sandwich = sandwich_orders.pop()
finished_sandwiches.append(sandwich)
print(f'I made your {sandwich} sandwich')
print("\n")
for sandwich in finished_sandwiches:
print(f"I made a {sandwich} sandwich.")
练习 7.10 梦想中的度假胜地
编写一个程序,调查用户梦想中的度假胜地。使用类似于“If you could visit one place in the world, where would you go?”的提示,并编写一个打印调查结果的代码块。
name_prompt = "\nWhat's your name?"
place_prompt = "If you could visit one place in the world, where would it be? "
continue_prompt = "Would you like to let someone else respond? (yes/no) "
response = {}
while True:
name = input(name_prompt)
place = input(place_prompt)
response[name] = place
repeat = input(continue_prompt)
if repeat == 'no':
break
print('\n')
for name,place in response.items():
print(f"{name.title()} would like to visit {place.title()}.")
运行结果
What's your name?zzy
If you could visit one place in the world, where would it be? hongkong
Would you like to let someone else respond? (yes/no) yes
What's your name?zzyy
If you could visit one place in the world, where would it be? shenyang
Would you like to let someone else respond? (yes/no) no
Zzy would like to visit Hongkong.
Zzyy would like to visit Shenyang.
- 2025-02-25
-
发表了主题帖:
《Python编程:从入门到实践(第3版)》读书笔记5:字典
本帖最后由 逝逝逝 于 2025-2-27 15:14 编辑
第六章 字典
6.1 一个简单的字典
下面是一个简单的字典,存储了有关特定外星人的信息
alien_0 = {'color':'green','points':5}
print(alien_0['color'])
print(alien_0['points'])
运行结果
green
5
6.2 使用字典
在 Python 中,字典(Dictionary)是一种键值对(Key-Value)存储结构,支持高效的数据查询和动态操作。
字典的创建与初始化
基本语法
# 空字典
empty_dict = {}
empty_dict = dict()
# 直接初始化
person = {
"name": "Alice",
"age": 30,
"city": "New York"
}
# 从键值对列表创建
items = [("a", 1), ("b", 2)]
my_dict = dict(items) # {'a': 1, 'b': 2}
基础操作
访问值
print(person["name"]) # 输出: Alice
# print(person["height"]) # KeyError(键不存在)
# 使用 get() 避免 KeyError
height = person.get("height", 170) # 默认值 170
print(height) # 170
添加/修改键值对
person["email"] = "alice@example.com" # 新增键值对
person["age"] = 31 # 修改已有键的值
删除键值对
del person["city"] # 删除键 "city"
email = person.pop("email") # 删除并返回 "email" 的值
练习 6.1 人
使用一个字典来存储一个人的信息,包括名、姓、年龄和居住的城市。该字典应包含键first_name、last_name、age和city。将存储在该字典中的每项信息都打印出来。
person = {
'first_name':'zheyuan',
'last_name':'zhang',
'age':'20',
'city' : 'weihai',
}
print(person['first_name'])
print(person['last_name'])
print(person['age'])
print(person['city'])
运行结果:
zheyuan
zhang
20
weihai
练习 6.2 喜欢的数 1
使用一个字典来存储一些人喜欢的数。请想出5个人的名字,并将这些名字用作字典中的键。再想出每个人喜欢的一个数,并将这些数作为值存储在字典中。打印每个人的名字和喜欢的数。为了让这个程序更有趣,通过询问朋友确保数据是真实的。
favorite_numbers = {
'zzy':1,
'zyx':2,
'zzyy':3,
'lcy':4,
'wsh':5,
}
num = favorite_numbers['zzy']
print(f"zzy's favorite number is {num}.")
num = favorite_numbers['zyx']
print(f"zyx's favorite number is {num}.")
num = favorite_numbers['zzyy']
print(f"zzyy's favorite number is {num}.")
num = favorite_numbers['lcy']
print(f"lcy's favorite number is {num}.")
num = favorite_numbers['wsh']
print(f"wsh's favorite number is {num}.")
运行结果
zzy's favorite number is 1.
zyx's favorite number is 2.
zzyy's favorite number is 3.
lcy's favorite number is 4.
wsh's favorite number is 5.
练习 6.3 词汇表 1
Python字典可用于模拟现实生活中的字典。为避免混淆,我们将后者称为词汇表。
想出你在前面学过的5个编程术语,将它们用作词汇表中的键,并将它们的含义作为值存储在词汇表中。
以整洁的方式打印每个术语及其含义。为此,既可以先打印术语,在它后面加上一个冒号,再打印其含义;也可以先在一行里打印术语,再使用换行符(\n)插入一个空行,然后在下一行里以缩进的方式打印其含义。
glossary = {
'string':'字符串',
'variable':'变量',
'list':'列表',
'tuple':'元组',
'dictionary':'字典',
}
word = 'string'
print(f"{word}\n\t{glossary['string']}")
word = 'variable'
print(f"{word}\n\t{glossary['variable']}")
word = 'list'
print(f"{word}\n\t{glossary['list']}")
word = 'tuple'
print(f"{word}\n\t{glossary['tuple']}")
word = 'dictionary'
print(f"{word}\n\t{glossary['dictionary']}")
6.3 遍历字典
遍历键
for key in person:
print(key)
for key in person.keys():
print(key)
遍历键值对
for key, value in person.items():
print(f"{key}: {value}")
遍历值
for value in person.values():
print(value)
练习 6.4 词汇表 2
现在你知道了如何遍历字典,请整理你为练习6.3编写的代码,将其中的一系列函数调用print()替换为一个遍历字典中键和值的循环。确保该循环正确无误后,再在词汇表中添加5个Python术语。当你再次运行这个程序时,这些新术语及其含义将自动包含在输出中。
glossary = {
'string':'字符串',
'variable':'变量',
'list':'列表',
'tuple':'元组',
'dictionary':'字典',
'key':'键',
'value':'值',
'set':'集合',
}
for word,explaination in glossary.items():
print(f"{word}\n\t{explaination}")
运行结果
string
字符串
variable
变量
list
列表
tuple
元组
dictionary
字典
key
键
value
值
set
集合
练习 6.5 河流
创建一个字典,在其中存储三条河流及其流经的国家。例如,一个键值对可能是'nile': 'egypt'。
使用循环为每条河流打印一条消息,如下所示。
The Nile runs through Egypt.
使用循环将该字典中每条河流的名字打印出来。
使用循环将该字典包含的每个国家的名字打印出来。
rivers= {
'nile':'egypt',
'yellow River':'china',
'yangtze River':'china',
}
for river,country in rivers.items():
print(f'The {river.title()} runs through {country.title()}. ')
for river in rivers.keys():
print(river.title())
for country in rivers.values():
print(country.title())
运行结果
The Nile runs through Egypt.
The Yellow River runs through China.
The Yangtze River runs through China.
Nile
Yellow River
Yangtze River
Egypt
China
China
练习 6.6 调查
在6.3.1节编写的程序favorite_languages.py中执行以下操作。
创建一个应该会接受调查的人的名单,其中有些人已在字典中,而其他人不在字典中。
遍历这个名单。对于已参与调查的人,打印一条消息表示感谢;对于还未参与调查的人,打印一条邀请参加调查的消息。
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name, language in favorite_languages.items():
print(f"{name.title()}'s favorite language is {language.title()}.")
print("\n")
coders = ['phil', 'josh', 'david', 'becca', 'sarah', 'matt', 'danielle']
for coder in coders:
if coder in favorite_languages.keys():
print(f"Thank you for taking the poll, {coder.title()}!")
else:
print(f"{coder.title()}, what's your favorite programming language?")
运行结果:
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
Thank you for taking the poll, Phil!
Josh, what's your favorite programming language?
David, what's your favorite programming language?
Becca, what's your favorite programming language?
Thank you for taking the poll, Sarah!
Matt, what's your favorite programming language?
Danielle, what's your favorite programming language?
6.4 嵌套
在 Python 中,字典和列表的嵌套可以构建复杂的数据结构,适用于处理多维数据(
1. 字典嵌套列表
定义与访问
# 定义:学生信息(每个学生有多个课程成绩)
students = {
"Alice": [85, 90, 78],
"Bob": [92, 88, 76],
}
# 访问 Alice 的第二个成绩
print(students["Alice"][1]) # 输出: 90
# 添加新学生及其成绩
students["Charlie"] = [80, 85, 90]
遍历与修改
# 遍历所有学生及其成绩
for name, scores in students.items():
avg = sum(scores) / len(scores)
print(f"{name}的平均分:{avg:.1f}")
# 修改 Bob 的第三个成绩
students["Bob"][2] = 80
2. 列表嵌套字典
定义与查询
# 定义:商品列表(每个商品是字典)
products = [
{"id": 1, "name": "Laptop", "price": 1200},
{"id": 2, "name": "Mouse", "price": 25},
]
# 查询第一个商品名称
print(products[0]["name"]) # 输出: Laptop
# 添加新商品
products.append({"id": 3, "name": "Keyboard", "price": 50})
筛选与更新
# 筛选价格高于 100 的商品
expensive = [p for p in products if p["price"] > 100]
print(expensive) # [{'id':1, 'name':'Laptop', 'price':1200}]
# 更新鼠标价格为 20
for p in products:
if p["name"] == "Mouse":
p["price"] = 20
3.字典嵌套字典
# 定义学生信息,每个学生有多个属性
students = {
"Alice": {"age": 25, "major": "CS", "grades": [90, 85]},
"Bob": {"age": 23, "major": "Math", "grades": [88, 92]},
}
遍历
for name, info in students.items():
print(f"学生: {name}")
for key, value in info.items():
print(f" {key}: {value}")
练习 6.7 人们
在为练习6.1编写的程序中,再创建两个表示人的字典,然后将这三个字典都存储在一个名为people的列表中。遍历这个列表,将其中每个人的所有信息都打印出来。
person_1 = {
'first_name':'zheyuan',
'last_name':'zhang',
'age':'20',
'city' : 'weihai',
}
person_2 = {
'first_name':'zheyuyang',
'last_name':'zhang',
'age':'20',
'city' : 'weihai',
}
person_3 = {
'first_name':'yuxiao',
'last_name':'zhou',
'age':'20',
'city' : 'weihai',
}
people = [person_1,person_2,person_3]
for person in people:
name = f"{person['first_name'].title()} {person['last_name'].title()}"
age = person['age']
city = person['city'].title()
print(f"{name}, of {city}, is {age} years old.")
运行结果
Zheyuan Zhang, of Weihai, is 20 years old.
Zheyuyang Zhang, of Weihai, is 20 years old.
Yuxiao Zhou, of Weihai, is 20 years old.
练习 6.8 宠物
创建多个表示宠物的字典,每个字典都包含宠物的类型及其主人的名字。将这些字典存储在一个名为pets的列表中,再遍历该列表,并将有关每个宠物的所有信息打印出来。
pet_1 = {
'animal type': 'cat',
'name': 'john',
'owner': 'zzy',
'weight': 43,
'eats': 'fish',
}
pet_2 = {
'animal type': 'chicken',
'name': 'mike',
'owner': 'zzyy',
'weight': 3,
'eats': 'seeds',
}
pet_3 = {
'animal type': 'dog',
'name': 'cherry',
'owner': 'zyx',
'weight': 30,
'eats': 'meet',
}
pets = [pet_1,pet_2,pet_3]
for pet in pets:
print(f"\n{pet['name'].title()} information:")
for key, value in pet.items():
print(f"\t{key}: {value}")
运行结果
John information
animal type: cat
name: john
owner: zzy
weight: 43
eats: fish
Mike information
animal type: chicken
name: mike
owner: zzyy
weight: 3
eats: seeds
Cherry information
animal type: dog
name: cherry
owner: zyx
weight: 30
eats: meet
练习 6.9 喜欢的地方
创建一个名为favorite_places的字典。在这个字典中,将三个人的名字用作键,并存储每个人喜欢的1~3个地方。为让这个练习更有趣些,让一些朋友说出他们喜欢的几个地方。
遍历这个字典,并将其中每个人的名字及其喜欢的地方打印出来。
favorite_places = {
'zzy':['Zhejiang'],
'zzyy':['Shenyang'],
'zyx':['Shandong','Zibo']
}
for name,places in favorite_places.items():
if len(places) == 1:
print(f"{name.title()}'s favorite place is:\n\t {places[0]}")
else:
print(f"{name.title()}'s favorite places are:")
for place in places:
print(f'\t{place}')
运行结果
Zzy's favorite place is:
Zhejiang
Zzyy's favorite place is:
Shenyang
Zyx's favorite places are:
Shandong
Zibo
练习 6.10 喜欢的数 2
修改为练习6.2编写的程序,让每个人都可以有多个喜欢的数字,然后将每个人的名字及其喜欢的数打印出来。
favorite_numbers = {
'zzy':[1,2],
'zyx':[2],
'zzyy':[3],
'lcy':[4],
'wsh':[5,6],
}
for name,nums in favorite_numbers.items():
if len(nums) == 1:
print(f"{name.title()}'s favotite number is: \n\t{nums[0]}")
else:
print(f"{name.title()}'s favotite number are:")
for num in nums:
print(f'\t{num}')
运行结果
Zzy's favotite number are:
1
2
Zyx's favotite number is:
2
Zzyy's favotite number is:
3
Lcy's favotite number is:
4
Wsh's favotite number are:
5
6
练习 6.11 城市
创建一个名为cities的字典,将三个城市名用作键。对于每座城市,都创建一个字典,并在其中包含该城市所属的国家、人口约数以及一个有关该城市的事实。表示每座城市的字典都
应包含country、population和fact等键。将每座城市的名字以及相关信息都打印出来。
cities = {
'city_1':{
'country':'China',
'population':'10000',
'fact':'big',
},
'city_2':{
'country':'America',
'population':'1000',
'fact':'small',
},
'city_3':{
'country':'Australia',
'population':'10000',
'fact':'good',
},
}
for city,feature in cities.items():
print(f"\ncityname:{city}")
print(f"\tcountry:{feature['country']}")
print(f"\tpopulation:{feature['population']}")
print(f"\tfact:{feature['fact']}")
运行结果
cityname:city_1
country:China
population:10000
fact:big
cityname:city_2
country:America
population:1000
fact:small
cityname:city_3
country:Australia
population:10000
fact:good
-
发表了主题帖:
《Python编程:从入门到实践(第3版)》读书笔记4:if语句
本帖最后由 逝逝逝 于 2025-2-25 20:28 编辑
第5章 if语句
5.1 一个简单的示例
书本用如下实例演示if语句
cars = ['audi','bmw','subaru','toyota']
for car in cars:
if car == 'bmw':
print(car.upper())
else:
print(car.title())
运行结果:
Audi
BMW
Subaru
Toyota
示例首先检查当前的汽车名是否是‘bmw'。如果是,就以全大写的方式打印,否则以首字母大写的方式打印。
5.2 条件测试
在大多数编程语言中,单个等号 ‘=’ 和 **双等号‘==’是完全不同的操作符,分别用于不同的场景:
’=‘是赋值操作符,将右侧的值或对象赋值给左侧的变量,用于变量初始化或修改变量的值,不是表达式,没有返回值(不能直接用于条件判断)。
`==`是等于比较符,比较两个值是否相等,返回布尔值 ’True‘ 或 ‘False’。用于条件判断、循环等逻辑操作,可以比较所有数据类型(数字、字符串、列表等)。
要判断两个值是否不等,可使用不等运算符(!=),书本示例
requested_topping = 'mushrooms'
if requested_topping != 'anchovies':
print('Hold the anchovies!')
运行结果
Hold the anchovies!
我们编写的大多数条件表达式会检查两个值是否相等,但有时候检查两个值是否不等的效率更高。
在 Python 中,and 和 or是逻辑运算符,用于组合多个条件判断。
‘and’运算符要求所有条件同时为真,才会返回 ‘True’。
‘or’运算符要求至少一个条件为真,就会返回’True‘。
‘and’的优先级高于‘or’(类似于乘法和加法的优先级关系),强烈建议用括号明确优先级,避免歧义。
‘and’/‘or’:逻辑运算符,用于布尔条件判断。
‘&’/‘|’:位运算符,用于二进制位操作(常见于整数运算)。
要判断特定的值是否在列表中,可使用关键字in,书中示例:
>>> requested_toppings = ['mushrooms','onions','pineapple']
>>> 'mushrooms' in requested_toppings
True
>>> 'pepperoni' in requested_toppings
False
相应的,关键词not in可以判断特定的值不在列而表中
在 Python 中,布尔表达式(Boolean Expression)是返回 ‘True’ 或 ‘False’的逻辑判断,用于控制程序流程(如条件语句、循环)。
‘True’和 ‘False’是 Python 中的布尔类型常量。
视为‘False’的值:‘None’、‘0’、‘0.0’、空序列(‘""’、‘[]’、‘()’、‘{}’)、‘False’。
其他值视为’True‘:非零数字、非空对象、非空字符串等。
练习5.1 条件测试
编写一系列条件测试,将每个条件测试以及你对结果的预测和实际结果都打印出来。你编写的代码应类似于这样:
car = 'subaru'
print("Is car == 'subaru'? I predict True.")
print(car == 'subaru')
print("\nIs car == 'audi'? I predict False")
print(car == 'audi')
详细研究实际结果,知道你明白它为何为True或False
创建至少10个条件测试,而且结果为True和False的条件测试分别至少有5个。
car = 'Subaru'
print("Is car == 'Subaru'? I predict True.")
print(car == 'Subaru')
print("\nIs car == 'Audi'? I predict False.")
print(car == 'Audi')
print("\nIs car.lower() == 'subaru'? I predict True.")
print(car.lower() == 'subaru')
print("\nIs car.lower() == 'Subaru'? I predict False.")
print(car.lower() == 'Subaru')
age = 21
print("\nIs age == 21? I predict True.")
print(age == 21)
print("\nIs age >= 22? I predict False.")
print(age >= 22)
age_1 = 22
age_2 = 18
print("\nIs age_1 >= 21 and age_2 <= 20? I predict True.")
print(age_1 >= 21 and age_2 <= 20)
print("\nIs age_1 >= 23 or age_2 <=17? I predict False.")
print(age_1 >= 23 or age_2 <=17)
numbers = ['1','2','3']
print("\nIs '1' in numbers? I predict True.")
print('1' in numbers)
print("\nIs '1' not in numbers? I predict False.")
print('1' not in numbers)
运行结果
Is car == 'Subaru'? I predict True.
True
Is car == 'Audi'? I predict False.
False
Is car.lower() == 'subaru'? I predict True.
True
Is car.lower() == 'Subaru'? I predict False.
False
Is age == 21? I predict True.
True
Is age >= 22? I predict False.
False
Is age_1 >= 21 and age_2 <= 20? I predict True.
True
Is age_1 >= 23 or age_2 <=17? I predict False.
False
Is '1' in numbers? I predict True.
True
Is '1' not in numbers? I predict False.
False
5.3 if语句
在 Python 中,‘if’ 语句用于根据条件执行不同的代码分支,是程序逻辑控制的核心工具。
1.基础语法
单条件判断
if 条件:
# 条件为 True 时执行的代码
示例
age = 18
if age >= 18:
print("已成年")
2. 多分支结构
‘if-elif-else’链
if 条件1:
# 条件1为 True 时执行
elif 条件2:
# 条件2为 True 时执行
else:
# 所有条件均为 False 时执行
示例
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B" # 此分支会被执行
elif score >= 60:
grade = "C"
else:
grade = "D"
print(f"成绩等级:{grade}") # 输出: 成绩等级:B
3. 嵌套 ’if‘语句
if 条件1:
if 条件2:
# 条件1和条件2均为 True 时执行
else:
# 条件1为 True,条件2为 False 时执行
else:
# 条件1为 False 时执行
示例
num = 15
if num % 2 == 0:
print("偶数")
else:
if num % 3 == 0:
print("奇数且能被3整除") # 输出
else:
print("奇数且不能被3整除")
4. 条件表达式(三元运算符)
简化简单的’if-else‘逻辑,适合赋值场景:
变量 = 值1 if 条件 else 值2
示例
age = 20
status = "成年" if age >= 18 else "未成年"
print(status) # 输出: 成年
5. 复合条件判断
结合逻辑运算符 `and`、`or`、`not` 处理多条件:
# 检查数字是否在 0 到 100 之间且为偶数
num = 42
if 0 <= num <= 100 and num % 2 == 0:
print("有效偶数")
6.测试多个条件
if-elif-else仅适用于只有一个条件满足的情况:遇到符合条件,余下的条件测试会被跳过。
在可能有多个条件为True,且需要在每个条件为True时采取相应措施时,适合使用这种方法。书本示例:
requested_toppings = ['mushrooms','extra cheese']
if 'mushrooms' in requested_toppings:
print("Adding mushrooms.")
if 'pepperoni' in requested_toppings:
print("Adding pepperoni.")
if 'extra cheese' in requested_toppings:
print("Adding extra cheese.")
print("\nFinished making your pizza!")
运行结果:
Adding mushrooms.
Adding extra cheese.
Finished making your pizza!
练习 5.3 外星人颜色 1
假设玩家在游戏中消灭了一个外星人,请创建一个名为alien_color的变量,并将其赋值为'green'、'yellow'或'red'。
编写一条if语句,测试外星人是否是绿色的。如果是,就打印一条消息,指出玩家获得了5分。
编写这个程序的两个版本,上述条件测试在其中的一个版本中通过,在另一个版本中未通过(未通过条件测试时没有输出)。
alien_color = 'green'
if alien_color == 'green':
print("Earn 5 points!")
运行结果
Earned 5 points!
alien_color = 'red'
if alien_color == 'green':
print("Earn 5 points!")
这个版本没有输出
练习 5.4 外星人颜色 2
像练习5.3那样设置外星人的颜色,并编写一个if-else结构。
如果外星人是绿色的,就打印一条消息,指出玩家因消灭该外星人获得了5分。
如果外星人不是绿色的,就打印一条消息,指出玩家获得了10分。
编写这个程序的两个版本,在一个版本中将执行if代码块,在另一个版本中将执行else代码块。
alien_color = 'green'
if alien_color == 'green':
print("Earn 5 points!")
else:
print("Earn 10 points!")
运行结果
Earn 5 points!
另一版本
alien_color = 'red'
if alien_color == 'green':
print("Earn 5 points!")
else:
print("Earn 10 points!")
运行结果
Earn 10 points!
练习 5.5 外星人颜色 3
将练习5.4中的if-else结构改为if-elif-else结构。
如果外星人是绿色的,就打印一条消息,指出玩家获得了5分。
如果外星人是黄色的,就打印一条消息,指出玩家获得了10分。
如果外星人是红色的,就打印一条消息,指出玩家获得了15分。
编写这个程序的三个版本,分别在外星人为绿色、黄色和红色时打印一条消息。
alien_color = 'red' # 另两版本修改此处
if alien_color == 'green':
print("Earn 5 points!")
elif alien_color == 'yellow':
print("Earn 10 points!")
else:
print("Earn 15 points!")
运行结果
Earn 15 points!
练习 5.6 人生的不同阶段
设置变量age的值,再编写一个if-elif-else结构,根据age的值判断这个人处于人生的哪个阶段。
如果年龄小于2岁,就打印一条消息,指出这个人是婴儿。
如果年龄为2(含)~4岁,就打印一条消息,指出这个人是幼儿。
如果年龄为4(含)~13岁,就打印一条消息,指出这个人是儿童。
如果年龄为13(含)~18岁,就打印一条消息,指出这个人是少年。
如果年龄为18(含)~65岁,就打印一条消息,指出这个人是中青年人。
如果年龄达到65岁,就打印一条消息,指出这个人是老年人。
age = 21
if age < 2:
identity = 'a baby'
elif age < 4:
identity = 'a toddler'
elif age < 13:
identity = 'a kid'
elif age < 18:
identity = 'a teenager'
elif age < 65:
identity = 'an adult'
else:
identity = 'an elder'
print(f'You are {identity}')
运行结果
You are an adult
练习 5.7 喜欢的水果
创建一个列表,其中包含你喜欢的水果,再编写一系列独立的if语句,检查列表中是否包含特定的水果。
将该列表命名为favorite_fruits,并让其包含三种水果。
编写5条if语句,每条都检查某种水果是否在列表中。如果是,就打印一条像下面这样的消息。
You really like bananas!
favorite_fruits = ['bananas','apples','oranges']
if 'bananas' in favorite_fruits:
print('You really like bananas!')
if 'apples' in favorite_fruits:
print('You really like apples!')
if 'oranges' in favorite_fruits:
print('You really like oranges!')
if 'pears' in favorite_fruits:
print('You really like pears!')
if 'grapes' in favorite_fruits:
print('You really like grapes!')
运行结果
You really like bananas!
You really like apples!
You really like oranges!
5.4 使用if语句处理列表
在 Python 中,结合if语句处理列表是常见操作,可以实现元素过滤、条件判断、数据转换等功能。
1. 检查列表是否为空
my_list = []
if not my_list:
print("列表为空") # 输出
else:
print("列表非空")
2. 检查元素是否存在
fruits = ["apple", "banana", "cherry"]
target = "banana"
if target in fruits:
print(f"{target} 在列表中") # 输出
else:
print(f"{target} 不在列表中")
3. 遍历列表并应用条件
筛选符合条件的元素
numbers = [10, 5, 20, 3, 15]
filtered = []
for num in numbers:
if num > 10:
filtered.append(num)
print(filtered) # 输出: [20, 15]
修改符合条件的元素
numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers)):
if numbers[i] % 2 == 0:
numbers[i] *= 2 # 偶数翻倍
print(numbers) # 输出: [1, 4, 3, 8, 5]
4.使用列表推导式 +’if‘
基本筛选
numbers = [10, 5, 20, 3, 15]
filtered = [x for x in numbers if x > 10]
print(filtered) # 输出: [20, 15]
条件转换
# 将偶数转为字符串,奇数保持原样
numbers = [1, 2, 3, 4]
result = [str(x) if x % 2 == 0 else x for x in numbers]
print(result) # 输出: [1, '2', 3, '4']
练习 5.8 以特殊方式跟管理员打招呼
创建一个至少包含5个用户名的列表,并且其中一个用户名为'admin'。想象你要编写代码,在每个用户登录网站后都打印一条问候消息。遍历用户名列表,向每个用户打印一条问候
消息。
如果用户名为'admin',就打印一条特殊的问候消息,如下所示。
Hello admin, would you like to see a status report?
否则,打印一条普通的问候消息,如下所示。
Hello Jaden, thank you for logging in again.
users = ['a','b','c','d','admin']
for user in users:
if user == 'admin':
print('Hello admin, would you like to see a status report?')
else:
print('Hello Jaden, thank you for loggin in again!')
运行结果
Hello Jaden, thank you for loggin in again!
Hello Jaden, thank you for loggin in again!
Hello Jaden, thank you for loggin in again!
Hello Jaden, thank you for loggin in again!
Hello admin, would you like to see a status report?
练习 5.9 处理没有用户的情形
在为练习5.8编写的程序中,添加一条if语句,检查用户名列表是否为空。
如果为空,就打印如下消息。
We need to find some users!
删除列表中的所有用户名,确认将打印正确的消息
users = []
if users:
for user in users:
if user == 'admin':
print('Hello admin, would you like to see a status report?')
else:
print('Hello Jaden, thank you for loggin in again!')
else:
print('We need to find some users!')
运行结果
We need to find some users!
练习 5.10 检查用户名
按照下面的说明编写一个程序,模拟网站如何确保每个用户的用户名都独一无二。
创建一个至少包含5个用户名的列表,并将其命名为current_users。
再创建一个包含5个用户名的列表,将其命名为new_users,并确保其中有一两个用户名也在列表current_users中。
遍历列表new_users,检查其中的每个用户名是否已被使用。如果是,就打印一条消息,指出需要输入别的用户名;否则,打印一条消息,指出这个用户名未被使用。
确保比较时不区分大小写。换句话说,如果用户名'John'已被使用,应拒绝用户名'JOHN'。(为此,需要创建列表current_users的副本,其中包含当前所有用户名的全小写版本。)
current_users = ['a','b','c','d','e']
new_users = ['f','g','h','i','a']
current_users_2 = [current_user.lower() for current_user in current_users]
for new_user in new_users:
if new_user in current_users_2:
print(f"{new_user} has been used")
else:
print(f"{new_user} is still available.")
运行结果
f is still available.
g is still available.
h is still available.
i is still available.
a has been used
练习 5.11 序数
序数表示顺序位置,如1st和2nd。序数大多以th结尾,只有1st、2nd、3rd例外。
在一个列表中存储数字1~9。
遍历这个列表。
在循环中使用一个if-elif-else结构,打印每个数字对应的序数。输出内容应为"1st 2nd 3rd 4th 5th 6th 7th 8th 9th",每个序数都独占一行。
nums = [1,2,3,4,5,6,7,8,9]
for num in nums:
if num == 1:
print('1st')
elif num == 2:
print('2nd')
else:
print(f'{num}th')
运行结果
1st
2nd
3th
4th
5th
6th
7th
8th
9th
5.5 设置if 语句的格式
PEP8唯一建议:在诸如==,>=,<=等比较运算符两边各添加一个空格。例如
if age < 4:
要比
if age<4:
更好。
- 2025-02-23
-
发表了主题帖:
《Python编程:从入门到实践(第3版)》读书笔记3:操作列表
本帖最后由 逝逝逝 于 2025-2-24 16:43 编辑
第4章 操作列表
4.1 遍历整个列表
用for循环遍历列表,书本示例:
magicians = ['alice','david','carolina']
for magician in magicians:
print(magician)
运行结果
alice
david
carolina
编写for循环时,选择描述单个列表元素的有意义的名称作为临时变量名称,例如
for cat in cats:
for dog in dogs:
for item in list_of_items:
4.2 避免缩进错误
写完for循环后回车,会自动缩进,之后的代码都会缩进,他们都是for循环的内容,直到有一行代码不缩进。
在 Python 的 ‘for’ 循环中,缩进决定了代码的归属关系,错误的缩进会导致语法错误(如 ‘IndentationError’)或逻辑错误。
缩进规则
缩进范围为‘for’ 循环的冒号 ’:‘ 后的所有缩进代码属于循环体。统一缩进单位为4个空格(推荐)或 1个制表符(Tab),不可混用。取消缩进即表示退出循环体。
除了书中常见的缩进错误,再补充两种
错误1:缩进不一致
错误示例
magicians = ['alice','david','carolina']
for magician in magicians:
print(magician)
print('Hello,eeworld')# 缩进3个空格(与上一行不一致)
报错
File "c:/Users/ASUS/OneDrive/Desktop/python_work/draft.py", line 4
print('Hello,eeworld')
^
IndentationError: unindent does not match any outer indentation level
正确写法
magicians = ['alice','david','carolina']
for magician in magicians:
print(magician)
print('Hello,eeworld')# 统一缩进4个空格
运行结果
alice
Hello,eeworld
david
Hello,eeworld
carolina
Hello,eeworld
错误2:嵌套循环的缩进混乱
错误示例
for i in range(2):
for j in range(2): # 未缩进,报错
print(i, j)
报错
File "c:/Users/ASUS/OneDrive/Desktop/python_work/draft.py", line 2
for j in range(2): # 未缩进,报错
^
IndentationError: expected an indented block after 'for' statement on line 1
正确写法
for i in range(2):
for j in range(2):# 缩进一级
print(i, j)# 缩进两级
运行结果
0 0
0 1
1 0
1 1
练习 4.1 比萨
想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for循环将每种比萨的名称打印出来。
修改这个for循环,使其打印包含比萨名称的句子,而不仅仅是比萨的名称。对于每种比萨都显示一行输出,如下所示。
I like pepperoni pizza.
在程序末尾添加一行代码(不包含在for循环中),指出你有多喜欢比萨。输出应包含针对每种比萨的消息,还有一个总结性的句子,如下所示。
I really love pizza!
pizzas = ['pizza1','pizza2','pizza3']
for pizza in pizzas:
print(pizza)
for pizza in pizzas:
print(f'I like {pizza}.')
print('I really like pizza!')
运行结果
pizza1
pizza2
pizza3
I like pizza1.
I like pizza2.
I like pizza3.
I really like pizza!
练习 4.2 动物
想出至少三种有共同特征的动物,将其名称存储在一个列表中,再使用for循环将每种动物的名称打印出来。
修改这个程序,使其针对每种动物都打印一个句子,如下所示。
A dog would make a great pet.
在程序末尾添加一行代码,指出这些动物的共同之处,如打印下面这样的句子。
Any of these animals would make a great pet!
animals = ['dog','cat','hamster']
for animal in animals:
print(f'A {animal} would make a great pet')
print('Any of these animals would make a great pet')
运行结果
A dog would make a great pet
A cat would make a great pet
A hamster would make a great pet
Any of these animals would make a great pet
4.3 创建数值列表
在Python中,‘range()`’函数用于生成一个不可变的整数序列,通常用于循环控制或生成数值范围。
基本语法
range(stop) # 生成 0 到 stop-1 的整数序列(步长默认为1)
range(start, stop) # 生成 start 到 stop-1 的整数序列
range(start, stop, step) # 按指定 step 生成序列(可为正或负)
特性:‘range()’ 返回一个‘range’对象,而非实际列表,仅在需要时计算值,节省内存。
r = range(1, 5) # 生成 range(1, 5)
print(list(r)) # 转换为列表: [1, 2, 3, 4]
支持索引和切片:可以像列表一样访问元素或切片,但不可修改(不可变)。
r = range(10)
print(r[2]) # 输出: 2
print(r[2:5]) # 输出: range(2, 5)
参数灵活,步长可为正或负:
# 正步长(递增)
print(list(range(1, 10, 2))) # 输出: [1, 3, 5, 7, 9]
# 负步长(递减)
print(list(range(5, 0, -1))) # 输出: [5, 4, 3, 2, 1]
常见用途
1.循环控制
# 遍历 0 到 4
for i in range(5):
print(i) # 输出: 0 1 2 3 4
2.遍历列表索引
fruits = ["apple", "banana", "cherry"]
for i in range(len(fruits)):
print(fruits[i])
3.生成数值序列
# 生成 0 到 9 的偶数列表
even_numbers = list(range(0, 10, 2)) # [0, 2, 4, 6, 8]
注意事项
‘stop‘值不包含:序列范围为 ‘[start, stop)’,这是编程语言常见的差一行为的结果,在上一篇帖子中的切片规则也体现了这一点。
print(list(range(2, 5))) # 输出: [2, 3, 4]
步长为0会报错,’step‘ 不能为 ’0‘。
range(1, 5, 0)
报错:
Traceback (most recent call last):
File "c:/Users/ASUS/OneDrive/Desktop/python_work/draft.py", line 1, in <module>
range(1, 5, 0)
ValueError: range() arg 3 must not be zero
负步长需满足条件:当 ’step < 0‘时,需要 ’start > stop‘。
print(list(range(5, 1, -1))) # 输出: [5, 4, 3, 2]
在 Python 中,列表推导式(List Comprehension) 是一种简洁且高效的创建列表的方式,可以用一行代码替代传统的 ‘for’循环和 ‘if‘条件判断。
基本语法
[表达式 for 变量 in 可迭代对象]
表达式:对变量进行操作的表达式(可以是函数、计算等)。
变量:从可迭代对象中逐个取出的元素。
可迭代对象:如列表、字符串、‘range’对象等。
书本示例
#生成1到10的平方列表
squares = [value**2 for value in range(1,11)]
print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
补充一下带条件过滤的列表推导式,通过添加‘if‘条件筛选元素:
[表达式 for 变量 in 可迭代对象 if 条件]
示例
#筛选出0到9中的偶数
even_numbers = [x for x in range(10) if x % 2 == 0]
print(even_numbers) # 输出: [0, 2, 4, 6, 8]
补充一下多循环嵌套,支持多个 ’for‘循环,生成笛卡尔积或组合结果
[表达式 for 变量1 in 可迭代对象1 for 变量2 in 可迭代对象2]
示例
# 生成坐标点的笛卡尔积 (x, y)
coordinates = [(x, y) for x in range(3) for y in range(2)]
print(coordinates) # 输出: [(0,0), (0,1), (1,0), (1,1), (2,0), (2,1)]
列表推导式还可以处理字符串
# 将句子拆分成单词并转为大写
sentence = "hello eeworld"
uppercase_words = [word.upper() for word in sentence.split()]
print(uppercase_words) # 输出: ['HELLO', 'EEWORLD']
列表推导式通常比等效的 ’for‘ 循环更快,因为底层优化为 C 语言实现,且列表推导式内存高效:直接生成列表,无需中间变量。
注意如果逻辑过于复杂(如多层嵌套或大量条件),建议改用传统的 ’for`‘循环以提高可读性。
练习 4.3 数到 20
使用一个 for 循环打印数 1~20(含)。
for num in range(1,21):
print(num)
练习4.4 100万
创建一个包含数1~1 000 000的列表,再使用一个for循环将这些数打印出来。(如果输出的时间太长,按Ctrl+C停止输出,或关闭输出窗口)
nums =list(range(1,1000001))
for num in nums:
print(num)
练习 4.5 100 万求和
创建一个包含数1~1 000 000的列表,再使用min()和max()核实该列表确实是从1开始、到1 000 000结束的。另外,对这个列表调用函数sum(),看看Python将100万个数相加需要多少时间。
nums =list(range(1,1000001))
print(min(nums))
print(max(nums))
print(sum(nums))
Python将100万个数相加速度很快,几乎不需要时间.。
练习 4.6 奇数
通过给range()函数指定第三个参数来创建一个列表,其中包含1~20的奇数;再使用一个for循环将这些数打印出来。
odd_nums = list(range(1,20,2))
for odd_num in odd_nums:
print(odd_num)
练习 4.7 3 的倍数
创建一个列表,其中包含3~30内能被3整除的数,再使用一个for循环将这个列表中的数打印出来。
nums = [num for num in range(3,31) if num % 3 ==0]
for num in nums:
print(num)
这里我使用了列表推导式。
练习 4.8 立方
将同一个数乘三次称为立方。例如,在Python中,2的立方用2**3表示。创建一个列表,其中包含前10个整数(1~10)的立方,再使用一个for循环将这些立方数打印出来。
一般方法
nums = []
for num in range(1,11):
nums.append(num**3)
for num in nums:
print(num)
练习4.9 使用列表推导式
nums = [num**3 for num in range(1,11)]
for num in nums:
print(num)
4.3 创建数值列表
在 Python 中,切片(Slice) 是一种灵活且强大的操作,用于从序列(如列表、字符串、元组等)中提取子集。
基本语法
sequence[start:stop:step]
’start‘:起始索引(包含),默认为 ‘0’。
‘stop’:结束索引(不包含),默认为序列末尾。
‘step’:步长(可选),默认为 `1`。可为正数(从左到右)或负数(从右到左)。 示例:
1.列表切片
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 提取索引2到5(不包含5)
print(nums[2:5]) # 输出: [2, 3, 4]
# 从头到索引5(不包含5)
print(nums[:5]) # 输出: [0, 1, 2, 3, 4]
# 从索引3到末尾
print(nums[3:]) # 输出: [3, 4, 5, 6, 7, 8, 9]
# 步长为2,提取偶数索引元素
print(nums[::2]) # 输出: [0, 2, 4, 6, 8]
2.字符串切片
s = "Hello, eeworld!"
# 提取前5个字符
print(s[:5]) # 输出: "Hello"
负数索引与步长
负数索引:从右向左计数(`-1` 为最后一个元素)。
负步长:反向提取元素(需确保 `start > stop`)。
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 提取最后3个元素
print(nums[-3:]) # 输出: [7, 8, 9]
# 从索引5到2(反向,步长-1)
print(nums[5:2:-1]) # 输出: [5, 4, 3]
切片自动处理索引越界,返回有效部分:
nums = [0, 1, 2, 3]
print(nums[1:100]) # 输出: [1, 2, 3](stop超出范围)
print(nums[-10:2]) # 输出: [0, 1](start超出范围)
修改列表的子序列
nums = [0, 1, 2, 3, 4]
nums[1:4] = [10, 20, 30] # 替换索引1到3的元素
print(nums) # 输出: [0, 10, 20, 30, 4]
注意,反向切片需注意顺序
nums = [0, 1, 2, 3]
print(nums[3:0:-1]) # 输出: [3, 2, 1](不包含索引0,很容易搞错)
print(nums[::-2]) # 输出: [3, 1]
可利用切片使字符串反转
text = "eeworld"
print(text[::-1]) # 输出: "dlrowee"
可以使用切片复制列表,方法是同时省略起始索引和种终止索引([ : ]),两个列表并不关联,例如:
msg1 = ['Hello','eeworld']
msg2 = msg1[:]
print(msg1)
print(msg2)
# 验证两个列表确实不关联
msg1.append('!')
msg2.append('.')
print(msg1)
print(msg2)
运行结果:
['Hello', 'eeworld']
['Hello', 'eeworld']
['Hello', 'eeworld', '!']
['Hello', 'eeworld', '.']
如果不使用切片直接赋值,两列表就会直接相关:
msg1 = ['Hello','eeworld']
msg2 = msg1
print(msg2)
msg1.append('!')
print(msg1)
print(msg2) # 改变msg1的值,msg2也会随之改变
运行结果:
['Hello', 'eeworld']
['Hello', 'eeworld', '!']
['Hello', 'eeworld', '!']
这具体和Python变量定义有关,具体可参见读书笔记1”如何理解变量是标签“。
练习 4.11 你的比萨,我的比萨
在你为练习4.1编写的程序中,创建比萨列表的副本,并将其赋给变量friend_pizzas,再完成如下任务。
在原来的比萨列表中添加一种比萨。
在列表friend_pizzas中添加另一种比萨。
核实有两个不同的列表。为此,打印消息“My favorite pizzas are:”,再使用一个for循环来打印第一个列表;打印消息“My friend’s favorite pizzas are:”,再使用一个for循环来打印第二
个列表。核实新增的比萨被添加到了正确的列表中。
pizzas1 = ['pizza1','pizza2','pizza3']
pizzas2 = pizzas1[:]
pizzas1.append('pizza4')
pizzas2.append('pizza5')
print('My favorite pizzas are:')
for pizza in pizzas1:
print(pizza)
print("My friend's favorite pizzas are")
for pizza in pizzas2:
print(pizza)
练习 4.12 使用多个循环
在本节中,为节省篇幅,程序foods.py的每个版本都没有使用for循环来打印列表。请选择一个版本的foods.py,在其中编写两个for循环,将各个食品列表都打印出来。
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
my_foods.append('cannoli')
friend_foods.append('ice cream')
print("My favorite foods are:")
for food in my_foods:
print(food)
print("\nMy friend's favorite foods are:")
for food in friend_foods:
print(food)
运行结果:
My favorite foods are:
pizza
falafel
carrot cake
cannoli
My friend's favorite foods are:
pizza
falafel
carrot cake
ice cream
4.5 元组
在 Python 中,元组(Tuple) 是一种不可变的序列类型,用于存储多个有序元素。它与列表(List)类似,但关键区别在于元组不可修改。
基本语法
# 空元组
empty_tuple = ()
# 单元素元组(需加逗号,避免与普通括号混淆)
single_item = (42,) # 正确
not_a_tuple = (42) # 这是整数,不是元组
# 多元素元组
my_tuple = (1, "hello", 3.14)
my_tuple = 1, "hello", 3.14 # 括号可省略
元组具有不可变性(Immutability),元组一旦创建,元素不可修改、添加或删除。但若元素是可变对象(如列表),其内部数据可修改。
与列表类似,支持正负索引和切片:
my_tuple = (10, 20, 30, 40, 50)
print(my_tuple[1]) # 20
print(my_tuple[-1]) # 50
print(my_tuple[1:4]) # (20, 30, 40)
print(my_tuple[::2]) # (10, 30, 50)
元组可以保护数据不被修改
CONSTANTS = (3.14, 9.8) # 定义常量,防止意外修改
元组的创建和访问速度比列表快,适合存储大量静态数据。
元组内存占用更小,存储更紧凑。
练习 4.13 自助餐
有一家自助式餐馆,只提供5种简单的食品。请想出5种简单的食品,并将其存储在一个元组中。
使用一个for循环将该餐馆提供的5种食品都打印出来。
尝试修改其中的一个元素,核实Python确实会拒绝你这样做。
餐馆调整菜单,替换了两种食品。请编写一行给元组变量赋值的代码,并使用一个for循环将新元组的每个元素都打印出来。
foods = ('sandwich','bread','burger','cake','salad')
for food in foods:
print(food)
# food[0] = 'soup' 报错:TypeError: 'str' object does not support item assignment
foods = ('sandwich','bread','burger','soup','beef')
for food in foods:
print(food)
运行结果:
sandwich
bread
burger
cake
salad
sandwich
bread
burger
soup
beef
- 2025-02-22
-
发表了主题帖:
《Python编程:从入门到实践(第3版)》读书笔记2:列表简介
本帖最后由 逝逝逝 于 2025-2-22 21:31 编辑
第3章 列表
3.1 列表是什么
在 Python 中,列表(List)是一种有序、可变、可存储任意数据类型的集合容器,是 Python 最核心的数据结构之一。C 中的对应概念数组(Array),C 的数组是固定长度、固定类型的内存连续块,例:int arr[5] = {1, 2, 3, 4, 5};Java对应概念:ArrayList类(属于 `java.util` 包),Java 的 `ArrayList` 是动态数组,支持自动扩容和泛型类型约束,例:ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
Python 列表可存储任意类型的元素,甚至混合类型。例如mixed_list = [1, "hello", 3.14, True]合法,C 数组严格单一类型,声明时需指定类型(如 `int`、`char`)。Java `ArrayList`通过泛型指定单一类型(如 `ArrayList<String>`),但需装箱/拆箱(如 `Integer` vs `int`)。
练习3.1 姓名
names = ['zzy','zzyy','zyx','lcy']
print(names[0])
print(names[1])
print(names[2])
print(names[3])
运行结果
zzy
zzyy
zyx
lcy
练习3.2 问候语
使用练习3.1中的列表,但不打印每个朋友的姓名,而是为每人打印一条消息。每条消息都包含相同的问候语,但开头为相应朋友的姓名。
names = ['zzy','zzyy','zyx','lcy']
print(f'Hello,{names[0].title()}')
print(f'Hello,{names[1].title()}')
print(f'Hello,{names[2].title()}')
print(f'Hello,{names[3].title()}')
题目要求问候语开头应为朋友的姓名,但问候语一般为"Hello,...",题目本意可能想考察方法title(),不如吧题目改成“但朋友姓名应该大写”。
运行结果
Hello,Zzy
Hello,Zzyy
Hello,Zyx
Hello,Lcy
练习3.3 自己的列表
vehical = ['bike','car','motonbike']
print(f'I go to school by {vehical[0]}')
print(f'I go to school by {vehical[1]}')
print(f'I go to school by {vehical[2]}')
运行结果
I go to school by bike
I go to school by car
I go to school by motonbike
3.2 修改、添加和删除元素
除了书中的方法,还可以通过切片批量修改多个元素
my_list = ["a", "b", "c", "d", "e"]# 替换索引 1 到 3(不包含 3)的元素
my_list[1:3] = ["x", "y", "z"] # 新元素数量可多于切片范围
print(my_list) # 输出: ['a', 'x', 'y', 'z', 'd', 'e']
切片规则:
‘list[start:end] = new_elements’:替换 ‘[start, end)’ 区间内的元素(注意前闭后开),‘new_elements’可以是任意长度的可迭代对象(如列表、元组)
可以通过extend()方法在列表末尾添加多个元素(合并可迭代对象),可以合并另一个列表/可迭代对象到当前列表末尾。
my_list = ["a", "b"]
my_list.extend(["c", "d"]) # 添加多个元素
print(my_list) # 输出: ['a', 'b', 'c', 'd']
# 支持任意可迭代对象(字符串、元组等)
my_list.extend("xyz") # 输出: ['a', 'b', 'c', 'd', 'x', 'y', 'z']
可以通过+或+=拼接添加元素
# += 运算符(原地修改)
my_list = [1, 2]
my_list += [3, 4] # 等价于 extend()
print(my_list) # 输出: [1, 2, 3, 4]
# + 运算符(生成新列表)
new_list = my_list + [5, 6] # 原列表不变
print(new_list) # 输出: [1, 2, 3, 4, 5, 6]
del是语句不是方法
clear()方法可以清空列表所有元素
my_list = [1, 2, 3]
my_list.clear() # 清空列表
print(my_list) # 输出: []
练习 3.4 嘉宾名单
如果你可以邀请任何人一起共进晚餐(无论是在世的还是故去的),你会邀请哪些人?请创建一个列表,其中包含至少三个你想邀请的人,然后使用这个列表打印消息,邀请这些人都
来与你共进晚餐。
name = ['zzyy','zyx','lcy']
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
运行结果
Zzyy,have dinner with me!
Zyx,have dinner with me!
Lcy,have dinner with me!
练习 3.5 修改嘉宾名单
你刚得知有位嘉宾无法赴约,因此需要另外邀请一位嘉宾。
以完成练习3.4时编写的程序为基础,在程序末尾添加函数调用print(),指出哪位嘉宾无法赴约。
修改嘉宾名单,将无法赴约的嘉宾的姓名替换为新邀请的嘉宾的姓名。
再次打印一系列消息,向名单中的每位嘉宾发出邀请。
name = ['zzyy','zyx','lcy']
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print(f'{name[0].title()} have no time.')
del name[0]
name.append('wsh')
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
运行结果
Zzyy,have dinner with me!
Zyx,have dinner with me!
Lcy,have dinner with me!
Zzyy have no time.
Zyx,have dinner with me!
Lcy,have dinner with me!
Wsh,have dinner with me!
练习 3.6 添加嘉宾
你刚找到了一张更大的餐桌,可容纳更多的嘉宾就座。请想想你还想邀请哪三位嘉宾。以完成练习3.4或练习3.5时编写的程序为基础,在程序末尾添加函数调用print(),指出你找到了一张更大的餐桌。
使用insert()将一位新嘉宾添加到名单开头。
使用insert()将另一位新嘉宾添加到名单中间。
使用append()将最后一位新嘉宾添加到名单末尾。
打印一系列消息,向名单中的每位嘉宾发出邀请。
name = ['zzyy','zyx','lcy']
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print(f'{name[0].title()} have no time.')
del name[0]
name.append('wsh')
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print('We get a bigger table!')
name.insert(0,'jjy')
name.insert(2,'lbw')
name.append('xyy')
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print(f'{name[3].title()},have dinner with me!')
print(f'{name[4].title()},have dinner with me!')
print(f'{name[5].title()},have dinner with me!')
运行结果
Zzyy,have dinner with me!
Zyx,have dinner with me!
Lcy,have dinner with me!
Zzyy have no time.
Zyx,have dinner with me!
Lcy,have dinner with me!
Wsh,have dinner with me!
We get a bigger table!
Jjy,have dinner with me!
Zyx,have dinner with me!
Lbw,have dinner with me!
Lcy,have dinner with me!
Wsh,have dinner with me!
Xyy,have dinner with me!
练习 3.7 缩短名单
你刚得知新购买的餐桌无法及时送达,因此只能邀请两位嘉宾。
以完成练习3.6时编写的程序为基础,在程序末尾添加一行代码,打印一条你只能邀请两位嘉宾共进晚餐的消息。
使用pop()不断地删除名单中的嘉宾,直到只有两位嘉宾为止。每次从名单中弹出一位嘉宾时,都打印一条消息,让该嘉宾知道你很抱歉,无法邀请他来共进晚餐。
对于余下两位嘉宾中的每一位,都打印一条消息,指出他依然在受邀之列。
使用del将最后两位嘉宾从名单中删除,让名单变成空的。打印该名单,核实名单在程序结束时确实是空的。
name = ['zzyy','zyx','lcy']
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print(f'{name[0].title()} have no time.')
del name[0]
name.append('wsh')
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print('We get a bigger table!')
name.insert(0,'jjy')
name.insert(2,'lbw')
name.append('xyy')
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print(f'{name[3].title()},have dinner with me!')
print(f'{name[4].title()},have dinner with me!')
print(f'{name[5].title()},have dinner with me!')
print('I can only have dinner with two people.')
print(f"Sorry, {name.pop().title()} there's no room at the table.")
print(f"Sorry, {name.pop().title()} there's no room at the table.")
print(f"Sorry, {name.pop().title()} there's no room at the table.")
print(f"Sorry, {name.pop().title()} there's no room at the table.")
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
del name[0]
del name[0]
print(name)
运行结果
Zzyy,have dinner with me!
Zyx,have dinner with me!
Lcy,have dinner with me!
Zzyy have no time.
Zyx,have dinner with me!
Lcy,have dinner with me!
Wsh,have dinner with me!
We get a bigger table!
Jjy,have dinner with me!
Zyx,have dinner with me!
Lbw,have dinner with me!
Lcy,have dinner with me!
Wsh,have dinner with me!
Xyy,have dinner with me!
I can only have dinner with two people.
Sorry, Xyy there's no room at the table.
Sorry, Wsh there's no room at the table.
Sorry, Lcy there's no room at the table.
Sorry, Lbw there's no room at the table.
Jjy,have dinner with me!
Zyx,have dinner with me!
[]
答案使用了注释和\n换行,先让这样更加清晰,这是我需要改进的地方。
在最后一个练习中,删除元素时下标是保持不变的,因为每删一个元素,列表都会改变,这点很容易出错。
方法符合逻辑是可以链式操作的,如name.pop().title()依然正确。
3.3 管理列表
Python中的sort()方法用于对列表进行原地排序(直接修改原列表),默认按升序排列。基本语法
list.sort(key=None, reverse=False)
key(可选): 指定一个函数,用于生成排序依据的值(如按长度、属性等)。
reverse(可选): 布尔值,`True` 表示降序,`False` 表示升序(默认)。
按自定义规则排序(`key`参数)
按字符串长度排序:
words = ["apple", "banana", "cherry"]
words.sort(key=len)
print(words) # 输出: ['apple', 'cherry', 'banana']
处理大小写混合的字符串:
letters = ['a', 'Z', 'B', 'c']
letters.sort(key=str.lower) # 忽略大小写排序
print(letters) # 输出: ['a', 'B', 'c', 'Z']
sort()方法是原地修改的,直接修改原列表,不返回新列表。若尝试接收返回值会得到 `None`:
a = [3, 1, 2]
b = a.sort() # 输出None
sorted()是内置函数,返回新列表,原列表不变:
a = [3, 1, 2]
b = sorted(a) # a 不变,b 是排序后的新列表
对于如何使用sorted()函数降序排序,书中仅说“可向sorted()函数传递参数reverse=Ture",应说明Python中函数/方法可以有多个参数,并辅以示例会更好。
sorted()函数基本语法
sorted(iterable, key=None, reverse=False)
iterable:要排序的可迭代对象(如列表、元组等)。
key(可选):自定义排序规则的函数(如按长度、属性等)。
reverse(可选):布尔值,`True` 表示降序,`False` 表示升序(默认)。
字符串列表降序排序
letters = ['a', 'z', 'B', 'c']
sorted_letters = sorted(letters, reverse=True)
print(sorted_letters) # 输出: ['z', 'c', 'a', 'B']
按自定义规则降序排序(`key`参数),按字符串长度降序
words = ["apple", "banana", "cherry"]
sorted_words = sorted(words, key=len, reverse=True)
print(sorted_words) # 输出: ['banana', 'cherry', 'apple']
忽略大小写的降序排序
letters = ['a', 'Z', 'B', 'c']
sorted_letters = sorted(letters, key=str.lower, reverse=True)
print(sorted_letters) # 输出: ['Z', 'c', 'B', 'a']
练习 3.8 放眼世界
想出至少5个你想去旅游的地方。
将这些地方存储在一个列表中,并确保其中的元素不是按字母顺序排列的。
按原始排列顺序打印该列表。不要考虑输出是否整洁,只管打印原始Python列表就好。
使用sorted()按字母顺序打印这个列表,不要修改它。
再次打印该列表,核实排列顺序未变。
使用sorted()按与字母顺序相反的顺序打印这个列表,不要修改它。
再次打印该列表,核实排列顺序未变。
使用reverse()修改列表元素的排列顺序。打印该列表,核实排列顺序确实变了。
使用reverse()再次修改列表元素的排列顺序。打印该列表,核实已恢复到原来的排列顺序。
使用sort()修改该列表,使其元素按字母顺序排列。打印该列表,核实排列顺序确实变了。
使用sort()修改该列表,使其元素按与字母顺序相反的顺序排列。打印该列表,核实排列顺序确实变了。
place = ['New York','Paris','Tokyo','Rome','London']
print(place)
print(sorted(place))
print(place)
print(sorted(place,reverse = True))
print(place)
place.reverse()
print(place)
place.reverse()
print(place)
place.sort()
print(place)
place.sort(reverse = True)
print(place)
运行结果
['New York', 'Paris', 'Tokyo', 'Rome', 'London']
['London', 'New York', 'Paris', 'Rome', 'Tokyo']
['New York', 'Paris', 'Tokyo', 'Rome', 'London']
['Tokyo', 'Rome', 'Paris', 'New York', 'London']
['New York', 'Paris', 'Tokyo', 'Rome', 'London']
['London', 'Rome', 'Tokyo', 'Paris', 'New York']
['New York', 'Paris', 'Tokyo', 'Rome', 'London']
['London', 'New York', 'Paris', 'Rome', 'Tokyo']
['Tokyo', 'Rome', 'Paris', 'New York', 'London']
练习 3.9 晚餐嘉宾
选择你为完成练习3.4~3.7而编写的一个程序,在其中使用len()打印一条消息,指出你邀请了多少位嘉宾来共进晚餐。
name = ['zzyy','zyx','lcy']
print(f'{name[0].title()},have dinner with me!')
print(f'{name[1].title()},have dinner with me!')
print(f'{name[2].title()},have dinner with me!')
print(len(name))
运行结果
Zzyy,have dinner with me!
Zyx,have dinner with me!
Lcy,have dinner with me!
3
练习 3.10 尝试使用各个函数
想想可存储到列表中的东西,如山川、河流、国家、城市、语言或你喜欢的任何东西。编写一个程序,在其中创建一个包含这些元素的列表。然后,至少把本章介绍的每个函数都使用一次来处理这个列表
题干中的”函数“改为“方法和函数”,是不是更好一些?
place = ['New York','Paris','Tokyo','Rome','London']
print(place)
place.append('Beijing')
print(place)
place.insert(6,'Sydney')
print(place)
del place[0]
print(place)
place.pop()
print(place)
place.remove('Tokyo')
print(place)
print(sorted(place))
print(place)
print(sorted(place,reverse = True))
print(place)
place.reverse()
print(place)
place.reverse()
print(place)
place.sort()
print(place)
place.sort(reverse = True)
print(place)
运行结果
['New York', 'Paris', 'Tokyo', 'Rome', 'London']
['New York', 'Paris', 'Tokyo', 'Rome', 'London', 'Beijing']
['New York', 'Paris', 'Tokyo', 'Rome', 'London', 'Beijing', 'Sydney']
['Paris', 'Tokyo', 'Rome', 'London', 'Beijing', 'Sydney']
['Paris', 'Tokyo', 'Rome', 'London', 'Beijing']
['Paris', 'Rome', 'London', 'Beijing']
['Beijing', 'London', 'Paris', 'Rome']
['Paris', 'Rome', 'London', 'Beijing']
['Rome', 'Paris', 'London', 'Beijing']
['Paris', 'Rome', 'London', 'Beijing']
['Beijing', 'London', 'Rome', 'Paris']
['Paris', 'Rome', 'London', 'Beijing']
['Beijing', 'London', 'Paris', 'Rome']
['Rome', 'Paris', 'London', 'Beijing']
3.3 使用列表时避免索引错误
始终确保索引范围在`0` 到 `len(list)-1`(正索引)和 `-1` 到 `-len(list)`(负索引)。
负索引就是倒着数第几个元素,这点书中并未指出。
练习3.11 有意引发错误
如果你还没有在程序中遇到索引错误,就尝试引发一个这种错误吧。在你的一个程序中修改索引以引发索引错误。在关闭程序前,务必消除这种错误。
msg = ['x','1','13','Y','Xx','A']
print(msg[-7])
运行结果
Traceback (most recent call last):
File "c:/Users/ASUS/OneDrive/Desktop/python_work/draft.py", line 2, in <module>
print(msg[-7])
~~~^^^^
IndexError: list index out of range
修改后
msg = ['x','1','13','Y','Xx','A']
print(msg[-6])
运行结果
x
- 2025-02-17
-
发表了主题帖:
《Python编程:从入门到实践(第3版)》读书笔记1:Python环境安装、变量和简单的...
第一章 起步
检查系统是否安装Python,命令提示符可以用快捷键Win+R,输入cmd更方便地打开。在终端窗口输入python(全部小写)回车,没有出现Python提示符(>>>),弹出Microsoft Store界面,说明系统并未安装Python,这里遵循书中建议选择在官网安装。
安装好Python后,系统会提示如何起动Python,“At your terminal,type "py" to launch Python",打开终端输入py即可。
出现Python提示符(>>>)后就可以输入命令,可先按Ctrl+Z再按回车键或执行命令exit()关闭终端会话,另外在本书中出现此提示符就说明是在终端进行的操作。
VS Code需要下载Python扩展,下载以下3个Microsoft提供的扩展即可,如果需要可以下载中文扩展。
在终端运行Python程序输入的命令不一定是书中所说的cd Desktop\python_work,正确地址应在文件资源管理器中查看。
代码运行如下:
C:\Users\ASUS>cd OneDrive\Desktop\python_work
C:\Users\ASUS\OneDrive\Desktop\python_work>dir
驱动器 C 中的卷是 OS
卷的序列号是 9896-F05E
C:\Users\ASUS\OneDrive\Desktop\python_work 的目录
2025/02/14 14:38 <DIR> .
2025/02/14 15:28 <DIR> ..
2025/02/14 15:58 28 hello_world.py
1 个文件 28 字节
2 个目录 83,642,363,904 可用字节
C:\Users\ASUS\OneDrive\Desktop\python_work>python hello_world.py
Hello Python world!
练习1.2:输入错误
1.语法错误(会引发错误),例如:
pint("Hello Python world!")#拼写错误:`print` → `pint`
运行结果:
NameError: name 'pint' is not defined. Did you mean: 'print'?#pint不是Python的内置函数或用户定义的函数,Python帮助定位拼写错误
2.逻辑错误(不会引发错误),例如:
print("Helo Python world!") # 字符串拼写错误:`Hello` → `Helo`
运行结果:
Helo Python world!# 语法正确,但输出内容错误
添加不会导致错误的输入错误的关键是语法正确,但逻辑错误,即代码符合Python语法规则,但功能或输出不符合预期因为Python仅验证语法规则,不检查代码的“意图”或“逻辑合理性”。
第2章 变量和简单的数据类型
2.2 变量
Python的变量命名规则与其他编程语言(如Java、C++、JavaScript等)在基础语法上相似,但在命名风格和约定上有些许差异。
1.基础语法相似
允许的字符:变量名可以包含字母、数字和下划线(`_`),但不能以数字开头。
关键字限制:不能使用 Python 的保留关键字(如 `if`、`class`、`def` 等)。
区分大小写:如 `name` 和 `Name‘ 是不同的变量。
2. 命名风格不同
Python 社区推荐使用小写字母和下划线组合的蛇形命名法(snake_case),如 `user_name`、`total_count`。
Java/C#:常用驼峰命名法(camelCase),如 `userName`、`totalCount`。
JavaScript:驼峰命名法为主,但也可用蛇形,取决于框架或团队规范。
C/C++:通常用蛇形或驼峰,取决于代码库风格。
常量命名:Python 中常量通常用全大写和下划线,如 `MAX_SIZE`,这与 Java 或 C++ 类似。
3. 关键字差异
Python 的关键字与其他语言部分重叠,但也有独特保留字,如’None‘(类似Java的‘null’)、‘True‘/’False‘(其他语言可能用 ’true‘/’false‘)。
某些语言(如 C++)允许使用保留字加前缀(如‘_Class’),但Python不鼓励这种做法。
在Python中,Traceback(回溯)是当程序发生错误或异常时,解释器输出的错误信息链。它详细展示了代码执行过程中触发错误的路径(即代码的调用堆栈),帮助开发者快速定位问题。一个典型的Traceback信息包含以下内容(按从下到上):
1.错误类型:最底层显示具体的错误类型(如’TypeError‘、’IndexError‘、‘NameError’)。
2.错误描述:解释错误的原因(如'unsupported operand type(s) for +: 'int' and 'str')。
3.代码调用路径:从错误发生点逐层向上回溯,显示触发错误的函数调用链。
4.代码位置:每个调用层级会显示文件名、行号及对应的代码片段。
阅读Traceback时也应从下往上读,以下是常见 Traceback 错误类型:
错误类型
原因示例
SyntaxError
语法错误(如缺少冒号 `:`)
NameError
使用了未定义的变量或函数名
TypeError
操作或函数应用于不兼容类型的对象
IndexError
访问列表/元组中不存在的索引
KeyError
访问字典中不存在的键
ZeroDivisionError
除以零操作
AttributeError
访问对象不存在的属性或方法
FileNotFoundError
尝试打开不存在的文件
如何理解变量是标签?
变量是对象的引用,变量不存储数据本身,而是指向对象 ,在 Python 中,所有数据(如整数、字符串、列表等)都是对象(Object),存在于内存中。 变量本身并不直接存储这些对象的值,而是通过引用(Reference)指向对象的内存地址。 可以将变量想象成贴在对象上的标签,而不是存储数据的容器,例如
a = 5 # 创建一个整数对象 5,变量 a 是它的标签
b = a # 变量 b 也指向同一个对象 5(现在有两个标签)
变量可以随时“撕下”并贴到其他对象上,变量的指向是动态的,赋值操作只是改变标签的位置,而不是修改原对象的值。 对于不可变对象(如整数、字符串),修改变量时会创建新对象。
a = 5 # a → 5
a = 10 # a 现在指向新的对象 10,原来的对象 5 依然存在(若没有其他标签指向它,会被回收)
与C/C++的对比:C/C++ 中的变量是内存地址的别名,直接存储值。赋值操作会覆盖原有内存中的值。
int a = 5; // 内存中分配空间存储 5
a = 10; // 修改内存中的值为 10
Python中的变量只是对象的标签,赋值操作是改变标签的指向,而不是修改内存中的值。
a = 5 # 标签 a 贴在对象 5 上
a = 10 # 标签 a 撕下并贴到新对象 10 上
通过示例理解“标签”行为
示例 1:不可变对象(整数、字符串等)
a = 5
b = a # a 和 b 都指向同一个对象 5
a = 10 # a 指向新对象 10,b 仍指向 5
print(a) # 输出 10
print(b) # 输出 5
示例 2:可变对象(列表、字典等)
list1 = [1, 2, 3]
list2 = list1 # list1 和 list2 指向同一个列表对象
list2.append(4) # 修改的是同一个对象
print(list1) # 输出 [1, 2, 3, 4]
由此可见:
1. 变量不拥有数据,只是引用对象
多个变量可以指向同一个对象(共享内存),对可变对象的修改会影响所有指向它的变量。
2. 不可变对象 vs.可变对象
不可变对象(如整数、字符串)修改变量会创建新对象,原对象不受影响。
可变对象(如列表、字典)直接修改对象内容时,所有引用该对象的变量会“看到”变化。
另外,当对象没有变量引用时,会被 Python 的垃圾回收机制自动销毁。 例如:`a = 5; a = 10`,对象 5 如果没有其他标签指向它,会被回收。
那么,Python为什么需要这样设计呢?
1.动态性和灵活性:变量可以随时指向不同类型的对象。
2.高效内存管理:多个变量共享大对象时避免重复存储(如大型列表)。
3.简化复杂结构:函数参数传递、对象共享等行为更直观。
常见误区:
误区 1:认为赋值是复制对象。
a = [1, 2]
b = a # b 和 a 指向同一个列表,不是复制!
b.append(3)
print(a) # 输出 [1, 2, 3]
误区 2:认为变量存储的是对象的值。
a = 5
b = a
a = 10 # 这里只是让 a 指向新对象,不影响 b
print(b) # 输出 5(因为 b 仍然指向原来的 5)
总结:“变量是标签” 强调 Python 的变量本质是对象的引用,理解这一概念能避免因共享可变对象导致的意外副作用。 通过 `id()` 函数可以查看变量的内存地址,验证变量指向的对象是否相同,例如:
a = 5
b = a
print(id(a) == id(b)) # 输出 True
a = 5
b = a
a = 10
print(id(a) == id(b)) # 输出 False
练习2.1:简单消息
message = "Hello eeworld!"
print(message)
运行结果:
Hello eeworld!
练习2.2:多条简单消息
message = "Hello eeworld!"
print(message)
message = "I love eeworld!"
print(message)
运行结果:
Hello eeworld!
I love eeworld!
2.3 字符串
使用方法修改字符串的大小写:
首字母大写
name = "ada lovelace"
print(name.title())
运行结果:
Ada Lovelace
全大写或全小写:
name = "ada lovelace"
print(name.upper())
print(name.lower())
运行结果:
ADA LOVELACE
ada lovelace
还有一个改变大小写的方法书中并未提到,capitalize()方法可以将字符串首字母大写,其余小写:
name = "ada lovelace"
print(name.capitalize())
运行结果:
Ada lovelace
在Python中,f字符串(f-strings) 是一种简洁高效的字符串格式化方式,全称为“格式化字符串字面值”(Formatted String Literals)。它通过在字符串前添加前缀 `f` 或 `F`,允许直接在字符串中嵌入表达式(变量、运算、函数调用等),使代码更简洁、可读性更强,下面是f字符串的一些用法,记忆时可记住f加引号的格式是固定的。
1. 直接插入变量
message = "Hello"
print(f"{message},eeworld!")
运行结果:
Hello,eeworld!
2. 嵌入表达式
a = 3
b = 5
print(f"{a} + {b} = {a + b}")
运行结果:
3 + 5 = 8
3. 调用方法或函数
text = "hello"
print(f"{text.title()},eeworld!")
运行结果:
Hello,eeworld!
import math
print(f"π ≈ {math.pi:.3f}")
运行结果:
π ≈ 3.142
注意,书中的删除空白的lstrip()、rstrip()、strip()方法删去的都是字符串两端的空白,中间的不能删除。
这些有关字符串的方法都不会改变原变量,除非将结果关联到原来的变量。
msg = ' eeworld.com'
print(msg.title())
print(msg)
print(msg.strip())
print(msg)
print(msg.removesuffix('.com'))
print(msg)
msg=(msg.title())
print(msg)
运行结果:
Eeworld.Com
eeworld.com
eeworld.com
eeworld.com
eeworld
eeworld.com
Eeworld.Com
练习2.3:个性化消息
name = 'Eric'
print(f'Hello {name},would you like to learn some Python today?')
运行结果:
Hello Eric,would you like to leran some python today?
练习2.4:调整名字的大小写
name = 'eeworld'
print(name.lower())
print(name.upper())
print(name.title())
运行结果:
eeworld
EEWORLD
Eeworld
练习2.5:名言1
print('Many people once said,"eeworld is the best technology forum in the world"')
运行结果:
Many people once said,"eeworld is the best technology forum in the world"
练习2.6:名言2
famous_person = 'Many people'
message = f'{famous_person} once said,"eeworld is the best technology forum in the world"'
print(message)
运行结果:
Many people once said,"eeworld is the best technology forum in the world"
练习2.7:删除人名中的空白
name = ' \teeworld\n '
print(name)
print(name.lstrip())
print(name.rstrip())
print(name.strip())
运行结果:
eeworld
eeworld
eeworld
eeworld
值得注意的是,\t和\n都属于空白。
练习2.8:文件扩展名
filename='python_notes.txt'
print(filename.removesuffix('.txt'))
运行结果:
python_notes
注意,删除的前后缀要用引号,因为他们也是字符串。
2.4 数
Python的整数类型支持无限精度,不会溢出,其他语言(如 C/Java)有固定位数限制,溢出会导致未定义行为或环绕。
Python中bool是int的子类,True对应1,False对应0,可直接参与数值运算,其他语言(如 C/Java)布尔值与整数严格区分,不能直接参与数值运算。
Python普通除法/返回浮点数,整除//返回向下取整结果,其他语言(如 C/Java)整数除法直接截断。
Python是动态类型,无需显式声明变量类型,类型在运行时自动推断,整数与浮点数自动提升,混合运算时,结果自动提升为更宽泛的类型(如int+float,结果为float),其他语言(如 C/Java)是静态类型,变量类型需显式声明,类型错误会在编译时报错,混合运算需使用强制类型转换手动转换类型。
练习2.9:数字8
print(5+3)
print(9-1)
print(2*4)
print(16//2)
运行结果:
8
8
8
8
题目要求只显示数字8,若用普通除法/则输出浮点数8.0,故使用整除//。
练习2.10最喜欢的数
favorite_number = 3
message = f"My favorite number is {favorite_number}."
print(message)
运行结果
My favorite number is 3.
2.5 注释
Python 注释的语法
1. 单行注释:以#开头,到行尾结束。
2. 多行注释(非官方语法,但常用方式):每行开头添加#。
其他语言(如Java/C)单行注释//,多行注释/*...*/。
2.6 Python之禅
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
1. 优美胜于丑陋
Beautiful is better than ugly.
代码应追求优雅和简洁,避免复杂或晦涩的实现。
2. 明确胜于隐晦
Explicit is better than implicit.
明确表达逻辑,避免依赖隐式行为。
3. 简单胜于复杂
Simple is better than complex.
优先选择简单的解决方案,避免过度设计。例如用列表推导替代多重循环。
4. 复杂胜于凌乱
Complex is better than complicated.
如果问题本身复杂,代码可以适当复杂,但需保持结构清晰(如模块化设计)。
5. 扁平胜于嵌套
Flat is better than nested.
减少嵌套层次(如避免深层循环或条件嵌套),提升可读性。
6. 稀疏胜于稠密
Sparse is better than dense.
适当使用空格和换行分隔代码块,避免一行代码过度拥挤。
7. 可读性很重要
Readability counts.
代码是给人读的,命名清晰、结构明确是关键(如用 `calculate_total` 而非 `calc`)。
8. 特殊情况不足以破坏规则
Special cases aren't special enough to break the rules.
即使面对特殊场景,也应遵循语言规范和设计原则。
9. 实用性胜过纯粹性
Practicality beats purity.
在追求理论完美(如设计模式)和实际需求之间,优先满足实用性。
10. 错误不应被静默传递
Errors should never pass silently.
明确处理异常(如用 `try/except` 而非忽略错误),避免隐藏问题。
11. 除非明确需要静默
Unless explicitly silenced.
若必须忽略错误,需显式声明(如 `except ValueError: pass` 并添加注释说明)。
12. 面对歧义,拒绝猜测
In the face of ambiguity, refuse the temptation to guess.
代码行为应明确,避免依赖解释器的隐式行为(例如不同类型比较)。
13. 应有一种(最好仅一种)明显的方式
There should be one—and preferably only one—obvious way to do it.
Python 鼓励统一的编程风格,避免多套语法实现同一功能(对比 Perl 的“多种方式”哲学)。
14. 尽管起初并非如此,但总比没有好
Although that way may not be obvious at first unless you're Dutch.
Python 的设计可能对新手不够直观(尤其是受 Guido 的荷兰背景影响),但逐步学习后会理解其优雅。
15. 做优于不做
Now is better than never.
快速迭代(MVP 模式)优于过度拖延,但需注意下一条的平衡。
16. 若不急,别急于动手
Although never is often better than *right* now.
若方案不够成熟(如临时补丁),有时不写代码反而更好。
17. 难以解释的实现,通常不是好方案
If the implementation is hard to explain, it's a bad idea.
复杂的代码难以维护,应重构为可解释的结构。
18. 易于解释的实现,可能是好方案
If the implementation is easy to explain, it may be a good idea.
清晰的逻辑通常是正确的选择。
19. 命名空间是个绝妙的主意!多加利用!
Namespaces are one honking great idea—let's do more of those!
合理使用模块、类和函数的作用域,避免命名冲突(如避免全局变量滥用)。
- 2025-02-08
-
回复了主题帖:
读书入围名单:《Python编程:从入门到实践(第3版)》
个人信息无误,确认可以完成阅读分享计划