目录
- Unit6 字典
- Unit7 用户输入和while()循环
- Unit8 函数
- Unit9类
Unit6 字典
你将学习如何访问和修改字典中的信息。鉴于字典可存储的信息量几乎不受限制,因此我们会演示如何遍历字典中的数据。另外,你还将学习存储字典的列表、存储列表的字典和存储字典的字典.
6.1 一个简单的字典
alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
输出;
green
5
6.2使用字典
在Python中,字典是一系列键—值对。每个键都与一个值相关联,你可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。
6.2.1访问字典中的值
alien_0 = {'color': 'green'}
print(alien_0['color'])
6.2.2 添加键—值对
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
6.2.3先创建一个空字典
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
6.2.4修改字典中的值
#直接赋值改变
alien_0 = {'color': 'green'}
print("The alien is " + alien_0['color'] + ".")
alien_0['color'] = 'yellow'
print("The alien is now " + alien_0['color'] + ".")
6.2.5删除键—值对
对于字典中不再需要的信息,可使用del语句将相应的键—值对彻底删除。使用del语句时,必须指定字典名和要删除的键。
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
del alien_0['points']
print(alien_0)
6.2.6由类似对象组成的字典
格式编辑要准确
6.3遍历字典
6.3.1 遍历所有的键—值对(既有键又有值)
格式要正确:for key , value in xxx.items()
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key, value in user_0.items():
print("\nKey: " + key)
print("Value: " + value)
6.3.2遍历字典中所有的键
for name in xxx.keys( )
遍历字典时,会默认遍历所有的键,因此,如果将上述代码中的for name in favorite_languages.keys():替换为for name in favorite_languages:,输出将不变。
6.3.3按顺序便利字典中所有的键
是.keys()不是key你缺一个s就很难写
字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的。
这不是问题,因为通常你想要的只是获取与键相关联的正确的值。要以特定的顺序返回元素,一种办法是在for循环中对返回的键进行排序。为此,可使用函数sorted()来获得按特定顺序排列的键列表的副本:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name in sorted(favorite_languages.keys()):
print(name.title() + ", thank you for taking the poll.")
6.3.4遍历字典中所有的值
是.values( )
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
print("The following languages have been mentioned:")
for language in favorite_languages.values():
print(language.title())
The following languages have been mentioned:
Python
C
Python
Ruby
很清楚的可以看到没有考虑是否重复。涉及的值很少时,这也许不是问题,但如果被调查者很多,最终的列表可能包含大量的重复项。为剔除重复项,可使用集合(set)。
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):
print(language.title())
6.4嵌套
有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套
6.4.1字典列表
#每一个外星人都是一个字典,然后把字典存放在列表中
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]
自动生成字典存放在列表中
for alien_number in range(100):重复100次 range()返回一系列数字,其唯一的用途是告诉Python我们要重复这个循环多少次
# 创建一个用于存储外星人的空列表
aliens = []
# 创建30个绿色的外星人
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
# 显示前五个外星人
for alien in aliens[:5]:
print(alien)
print("...")
# 显示创建了多少个外星人
print("Total number of aliens: " + str(len(aliens)))
#修改前三个alien
for alien in aliens[0:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 1
6.4.2在字典中存储列表¥¥¥
favorite_languages = {
'jen': ['python', 'ruby'],
'sarah': ['c'],
'edward': ['ruby', 'go'],
'phil': ['python', 'haskell'],
}
6.4.3在字典中存储字典
#users是一个字典,然后value也是一个字典
users = {
'aeinstein': {
'first': 'albert',
'last': 'einstein',
'location': 'princeton',
},
'mcurie': {
'first': 'marie',
'last': 'curie',
'location': 'paris',
},
}
for username, user_info in users.items():
print("\nUsername: " + username)
full_name = user_info['first'] + " " + user_info['last']
location = user_info['location']
print("\tFull name: " + full_name.title())
print("\tLocation: " + location.title())
请注意,表示每位用户的字典的结构都相同,虽然Python并没有这样的要求,但这使得嵌
套的字典处理起来更容易。倘若表示每位用户的字典都包含不同的键,for循环内部的代码将
更复杂。
6.5 小结
Unit7 用户输入和while()循环
将学习如何接受用户输入,让程序能够对其进行处理。在程序需要一个名字时,你需要提示用户输入该名字;程序需要一个名单时,你需要提示用户输入一系列名字。为此,你需要使用函数input()
7.1函数input()的工作原理
message = input("Tell me something, and I will repeat it back to you: ")
print(message)
函数input()接受一个参数:即要向用户显示的提示或说明,让用户知道该如何做
7.1.1编写清晰的函数
input()里面的内容加一个空格
有可能提示超过一行可以叠加
prompt = "If you tell us who you are, we can personalize the messages you see."
prompt += "\nWhat is your first name? "
name = input(prompt)
7.1.2使用int()来获取数值输入
input()函数输入的实际上是一个字符串,如果要做数值使用需要转换或者使用int()函数
7.1.3求模运算符%
利用%2判断奇数还是偶数
7.1.4在Python 2.7中获取输入
如果你使用的是Python 2.7,请使用raw_input()而不是input()来获取输入
7.2 while()循环简介
for循环用于针对集合中的每个元素都一个代码块
而while循环不断地运行,直到指定的条件不满足为止。
7.2.1使用while()循环
while active:
message = input(prompt)
7.2.2让用户选择何时退出
7.2.3使用标志
即使用布尔变量
7.2.4使用break退出循环
7.2.5在循环中使用continue来进行下一个循环
7.2.6避免无限循环
每个程序员都会偶尔因不小心而编写出无限循环,在循环的退出条件比较微妙时尤其如此。
如果程序陷入无限循环,可按Ctrl + C,也可关闭显示程序输出的终端窗口
有些编辑器(如Sublime Text)内嵌了输出窗口,这可能导致难以结束无限循环,因此不
得不关闭编辑器来结束无限循环。
7.3 使用while()循环来处理列表字典(for循环遍历的时候不应更改)
for循环是一种遍历列表的有效方式,但在for循环中不应修改列表,否则将导致Python难以
跟踪其中的元素。要在遍历列表的同时对其进行修改,可使用while循环。通过将while循环同列
表和字典结合起来使用,可收集、存储并组织大量输入,供以后查看和显示。
7.3.1在列表之间移动元素
关键代码部分
while unconfirmed_users:
current_user = unconfirmed_users.pop()
print("Verifying user: " + current_user.title())
confirmed_users.append(current_user)
7.3.2删除包含特定值的所有列表元素
在第3章中,我们使用函数remove()来删除列表中的特定值,这之所以可行,是因为要删除
的值在列表中只出现了一次。如果要删除列表中所有包含特定值的元素,该怎么办呢?
假设你有一个宠物列表,其中包含多个值为’cat’的元素。要删除所有这些元素,可不断运
行一个while循环,直到列表中不再包含值’cat’,如下所示:
while 'cat' in pets:
pets.remove('cat')
7.3.3使用用户输入来填充字典
可使用while循环提示用户输入任意数量的信息
responses = {}
# 设置一个标志,指出调查是否继续
polling_active = True
while polling_active:
# 提示输入被调查者的名字和回答
name = input("\nWhat is your name? ")
response = input("Which mountain would you like to climb someday? ")
# 将答卷存储在字典中
responses[name] = response
# 看看是否还有人要参与调查
repeat = input("Would you like to let another person respond? (yes/ no) ")
if repeat == 'no':
polling_active = False
# 调查结束,显示结果
print("\n--- Poll Results ---")
for name, response in responses.items():
print(name + " would like to climb " + response + ".")
7.4小结
Unit8 函数
函数是带名字的代码块,用于完成具体的工作
8.1定义函数
def greet_user():
"""显示简单的问候语"""
print("Hello!")
greet_user()
8.1.1 向函数传递信息
在函数greet_user()的定义中,变量username是一个形参——函数完成其工作所需的一项信息。在代码greet_user(‘jesse’)中,值’jesse’是一个实参。实参是调用函数时传递给函数的信息。我们调用函数时,将要让函数使用的信息放在括号内。greet_user(‘jesse’)中,将实参’jesse’传递给了函数greet_user(),这个值被存储在形参username中。
注意 大家有时候会形参、实参不分,因此如果你看到有人将函数定义中的变量称为实参或将函数调用中的变量称为形参,不要大惊小怪。
8.1.2实参和形参
8.2传递实参
向函数传递实参的方式很多,可使用位置实参,这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其中每个实参都由变量名和值组成;还可使用列表和字典。
8.2.1位置实参
def describe_pet(animal_type, pet_name):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('hamster', 'harry')
- 调用函数多次
- 位置实参的顺序很重要:使用位置实参来调用函数时,如果实参的顺序不正确,result可能出乎意料:
8.2.2关键字实参
关键字实参是传递给函数的名称—值对。你直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='harry', animal_type='hamster')
8.2.3默认值
def describe_pet(pet_name, animal_type='dog'):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
8.2.4等效的函数调用
鉴于可混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式
8.2.5 避免实参错误
等你开始使用函数后,如果遇到实参不匹配错误,不要大惊小怪。你提供的实参多于或少于函数完成其工作所需的信息时,将出现实参不匹配错误。
8.3返回值
可使用return语句将值返回到调用函数的代码行。返回值让你能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序
8.3.1返回简单值
有时候,需要让实参变成可选的,这样使用函数的人就只需在必要时才提供额外的信息。可使用默认值来让实参变成可选的。
8.3.2 让实参变成可选的
8.3.3 返回字典
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。例如,下面的函数接受姓名的组成部分,并返回一个表示人的字典
8.3.4 结合使用函数和while()循环
def get_formatted_name(first_name, last_name):
"""返回整洁的姓名"""
full_name = first_name + ' ' + last_name
return full_name.title()
# 这是一个无限循环!
while True:
print("\nPlease tell me your name:")
f_name = input("First name: ")
l_name = input("Last name: ")
formatted_name = get_formatted_name(f_name, l_name)
print("\nHello, " + formatted_name + "!")
8.4 传递列表
def greet_users(names):
"""向列表中的每位用户都发出简单的问候"""
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
8.4.1在函数中修改列表
# 首先创建一个列表,其中包含一些要打印的设计
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
# 模拟打印每个设计,直到没有未打印的设计为止
# 打印每个设计后,都将其移到列表completed_models中
while unprinted_designs:
current_design = unprinted_designs.pop()
#模拟根据设计制作3D打印模型的过程
print("Printing model: " + current_design)
completed_models.append(current_design)
# 显示打印好的所有模型
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
8.4.2禁止函数修改列表
这个列表变成了空的,原来的列表没有了。为解决这个问题,可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件。
要将列表的副本传递给函数,可以像下面这样做:
#通过引用列表副本来禁止函数修改列表
print_models(unprinted_designs[:], completed_models)
8.5传递任意数量的关键字实参
有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。
#下面的函数只有一个形参*toppings,但不管调用语句提供了多少实参,都可以塞进去
def make_pizza(*toppings):
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
形参名*toppings中的星号让Python创建一个名为toppings的空元组
8.5.1传递任意数量的实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
def make_pizza(size, *toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
8.5.2使用任意数量的关键字实参
#user_profile.py
def build_profile(first, last, **user_info):
"""创建一个字典,其中包含我们知道的有关用户的一切"""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile('albert', 'einstein',
location='princeton',
field='physics')
print(user_profile)
8.6 将函数存储在模块中
函数的优点之一是,使用它们可将代码块与主程序分离。通过给函数指定描述性名称,可让主程序容易理解得多。你还可以更进一步,将函数存储在被称为模块的独立文件中,再将模块导 入到主程序中。import语句允许在当前运行的程序文件中使用模块中的代码。
通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上。这还能让你在众多不同的程序中重用函数。将函数存储在独立文件中后,可与其他程序员共享这些文件而不是整个程序。知道如何导入函数还能让你使用其他程序员编写的函数库。
8.6.1导入整个模块
要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。
调用模块中的函数
import xxx
xxx.xx()
import pizza
pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
8.6.2导入特定的函数
- from module_name import function_name
- from module_name import function_0, function_1, function_2
使用逗号分隔函数名 - 若使用这种语法,调用函数时就无需使用句点。由于我们在import语句中显式地导入了函数make_pizza(),因此调用它时只需指定其名称。
from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
8.6.3使用as 给函数指定别名
from pizza import make_pizza as mp
8.6.4使用as给模版指定别名
import pizza as p
p.make_pizza(16, ‘pepperoni’)
8.6.5导入模块中的所有函数
使用星号( * )运算符可让Python导入模块中的所有函数:
from pizza import *
由于导入了每个函数,可通过名称来调用每个函数,而无需使用句点表示法然而,使用并非自己编写的大型模块时,最好不要采用这种导入方法:如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果:Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数
最佳的做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法
8.7 函数编写指南![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/f6fe9279af46a4167873b108f248f8dd.png)
8.8 小结
Unit9类
9.1创建和使用类
使用类几乎可以模拟任何东西。下面来编写一个表示小狗的简单类Dog——它表示的不是特定的小狗,而是任何小狗
9.1创建Dog类
- 方法__init_()
- 在Python 2.7中创建类时,需要做细微的修改——在括号内包含单词object:
class Dog(object):
--snip--
9.2 根据类创建实例
class Dog():
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
1.访问属性:例如my_dog.age (实例名.变量)
2. 调用方法
my_dog.sit()
my_dog.roll_over()
3. 创建多个实例my_dog = Dog(‘willie’, 6) your_dog = Dog(‘lucy’, 3)
9.2使用类与实例
你可以直接修改实例的属性
也可以编写方法以特定的方式进行修改。
9.2.1 Car类
9.2.2 给属性指定默认值
类中的每个属性都必须有初始值,哪怕这个值是0或空字符串
class Car():
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
--snip--
def read_odometer(self):
"""打印一条指出汽车里程的消息"""
print("This car has " + str(self.odometer_reading) + " miles on it.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
9.2.3修改属性的值
1. 直接修改属性的值
要修改属性的值,最简单的方式是通过实例直接访问它。下面的代码直接将里程表读数设置为23:my_new_car.odometer_reading = 23
2. 通过方法修改属性的值(调用一个类内函数来改变![代码描述](https://i-blog.csdnimg.cn/blog_migrate/4db13c0a13f0f952cce1f6d452eaefe8.png)
3. 通过方法对属性的值进行递增(其实还是类内函数)
9.3继承
编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
9.3.1子类的方法__init_( )
创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__()需要父类施以援手。
#在这个之前有class Car():
#xxxxxxxxxxxxxxxxx
class ElectricCar(Car):
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
"""的super()是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar的父类的方法__init__(),让ElectricCar实例包含父类的所有属性。父类也称为超类(superclass),名称super因此而得名。"""
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
9.3.2Python 2.7中的继承
super需要传入参数子类名与self
9.3.3给子类定义属性和方法
让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法
主要是新属性
class Car():
--snip--
class ElectricCar(Car):
"""Represent aspects of a car, specific to electric vehicles."""
def __init__(self, make, model, year):
"""
电动汽车的独特之处
初始化父类的属性,再初始化电动汽车特有的属性
"""
super().__init__(make, model, year)
self.battery_size = 70
"""调用完super()之后再补上新的属性"""
9.3.4重写父类的方法(就是重新写个方法覆盖掉)
对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
9.3.5将实例用作属性
使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类。
例如,不断给ElectricCar类添加细节时,我们可能会发现其中包含很多专门针对汽车电瓶的属性和方法。在这种情况下,我们可将这些属性和方法提取出来,放到另一个名为Battery的类中,并将一个Battery实例用作ElectricCar类的一个属性:
逻辑就是定义了一个新类然后,在需要使用的子类电动车里利用这个新类添加属性
调用的时候很特殊
my_tesla.battery.describe_battery()
9.3.6模拟实物(高效最好,实践出真知)
9.4 导入类
文件可能变得很长
为在这方面提供帮助,Python允许你将类存储在模块中
然后在主程序中导入所需的模块
9.4.1导入单个类
使用该模块的程序都必须使用更具体的文件名,如my_car.py。下面是模块car.py,其中只包含Car类的代码
下面来创建一个只包含Car类的模块(Car.py)
my_car.py
from car import Car
import语句让Python打开模块car,并导入其中的Car类。这样我们就可以使用Car类
9.4.2在一个模块中存储多个类
虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。类Battery和ElectricCar都可帮助模拟汽车,因此下面将它们都加入模块car.py中
9.4.3从一个模块中导入多个类
from car import Car, ElectricCar
9.4.4导入整个模块
import car
9.4.5导入模块中的所有类
from module_name import *
不推荐使用这种导入方式,其原因有二。
首先,如果只要看一下文件开头的import语句,就能清楚地知道程序使用了哪些类,将大有裨益;但这种导入方式没有明确地指出你使用了模块中的哪些类。
这种导入方式还可能引发名称方面的困惑。如果你不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。
这里之所以介绍这种导入方式,是因为虽然不推荐使用这种方式,但你可能会在别人编写的代码中见到它。
需要从一个模块中导入很多类时,最好导入整个模块,module_name.class_name语法来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但你清楚地知道在程序的哪些地方使用了导入的模块;你还避免了导入模块中的每个类可能引发的名称冲突。
9.4.6在一个模块中导入另一个模块
有时候,需要将类分散到多个模块中,以免模块太大,或在同一个模块中存储不相关的类。
将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况下,可在前一个模块中导入必要的类。
9.4.7自定义工作流程
9.5 Python标准库
要了解 Python 标准库,一个很不错的资源是网站 Python Module of the Week。请访问 http://pymotw.com/并查看其中的目录,在其中找一个你感兴趣的模块进行探索,或阅读模块 collections 和 random 的文档。