11.Python基础语法---07字典
字典
通过{}构建 as {key1:value1,key2:value2.....}
- 对key与value的要求:
- key需要是不可变的类型,str, int, float, decimal, complex, bool, tuple
- value可以取任何数据类型,还可以是一个字典
- 特性:
- 字典也是无序的
- 字典里面不能出现重复的Key,但不会报错(后面加入的Value,会替换原来Key对应的Value)。
- 优势与原理:
names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
查找速度快
为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的。假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。
第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。
dict就是第二种实现方式,给定一个名字,比如'Michael',dict在内部就可以直接计算出Michael对应的存放成绩的“页码”,也就是95这个数字存放的内存地址,直接取出来,所以速度非常快。
你可以猜到,这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样,取的时候才能根据key直接拿到value。
-
字典与列表比较
dict有以下几个特点:- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
dict是用空间来换取时间的一种方法。
1. 定义字典
在Python中,字典是一系列键—值值对,每个键都与一个值相关联,可以使用键来访问与之相关联的值。
与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将 任何Python对象用作字典中的值。
键—值对是两个相关联的值。指定键时,Python将返回与之相关联的值。
键和值之间用冒号分隔,而键—值对之间用逗号分隔。
在字典中,想存储多少个键—值对都可以。
示例:
alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
执行结果:
green
5
2.使用字典
2.1 访问字典中的值
要获取与键相关联的值,可依次指定字典名和放在方括号内的键,如下:
alien_0 = {'color': 'green', 'points': 5}
new_points = alien_0['points']
print("You just earned " + str(new_points) + " points!")
执行结果:
You just earned 5 points!
如果key不存在,dict就会报错:
>>> alien_0['weight']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'weight'
要避免key不存在的错误,有两种办法:
一是通过in判断key是否存在:
>>> 'weight' in alien_0
False
二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:
>>> alien_0.get('weight')
>>> alien_0.get('weight', 23)
23
注意:返回None的时候Python的交互环境不显示结果。
2.2 添加键—值对
字典是一种动态结构,可随时在其中添加键—值对。要添加键—值对,可依次指定字典名、用方括号括起的键和相关联的值。
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
执行结果:
{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'x_position': 0, 'y_position': 25}
注意:
键—值对的排列顺序与添加顺序不同。Python不关心键—值对的添加顺序,而只关心键和值之间的关联关系。字典自然就是无序的。
请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉。
重点:
需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key。
>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
关于可变不可变:详见10.Python基础语法---06集合 QA部分说明
2.3 修改字典中的值
要修改字典中的值,可依次指定字典名、用方括号括起的键以及与该键相关联的新值。
alien_0 = {'color': 'green'}
print("The alien is " + alien_0['color'] + ".")
alien_0['color'] = 'yellow'
print("The alien is now " + alien_0['color'] + ".")
执行结果:
The alien is green.
The alien is now yellow.
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}
print("Original position: " + str(alien_0['x_position']))
# Move the alien to the right.
# Figure out how far to move the alien based on its speed.
if alien_0['speed'] == 'slow':
x_increment = 1
elif alien_0['speed'] == 'medium':
x_increment = 2
else:
# This must be a fast alien.
x_increment = 3
# The new position is the old position plus the increment.
alien_0['x_position'] = alien_0['x_position'] + x_increment
print("New position: " + str(alien_0['x_position']))
执行结果:
Original position: 0
New position: 2
2.4 删除键—值对
对于字典中不再需要的信息,可使用del 语句将相应的键—值对彻底删除。使用del 语句时,必须指定字典名和要删除的键。
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
del alien_0['points']
print(alien_0)
执行结果:
{'color': 'green', 'points': 5}
{'color': 'green'}
示例:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
print("Sarah's favorite language is " +
favorite_languages['sarah'].title() +
".")
执行结果:
Sarah's favorite language is C.
person = {
'first_name':'Sunny',
'last_name':'Sun',
'age':38,
'city':'WenZhou'
}
print("first_name:\t", person['first_name'])
print("last_name:\t", person['last_name'])
print("age:\t", person['age'])
print("city:\t", person['city'])
执行结果:
first_name: Sunny
last_name: Sun
age: 38
city: WenZhou
luck_num = {'Sunny':23, 'Denny':24, 'Jeecy':69, 'Power':62, 'Paul':7 }
print('Sunny', ":", luck_num['Sunny'])
print('Denny', ":", luck_num['Denny'])
print('Power', ":", luck_num['Power'])
print('Paul', ":", luck_num['Paul'])
执行结果:
Sunny : 23
Denny : 24
Jeecy : 69
Power : 62
Paul : 7
languages = {
'数值类型':'数值类型。。。',
'字符串类型':'字符串类型。。。',
'布尔类型':'布尔类型。。。',
'循环': '循环。。。',
'迭代':'迭代。。。'
}
print("数值类型:", languages["数值类型"])
print("字符串类型:", languages["字符串类型"])
print("布尔类型:", languages["布尔类型"])
print("循环:", languages["循环"])
print("迭代:", languages["迭代"])
print("数值类型")
print()
print("\t", languages["数值类型"])
print("字符串类型")
print()
print("\t", languages["字符串类型"])
print("布尔类型")
print()
print("\t", languages["布尔类型"])
print("循环")
print()
print("\t", languages["循环"])
print("迭代")
print()
print("\t", languages["迭代"])
执行结果:
数值类型:数值类型。。。
字符串类型:字符串类型。。。
布尔类型:布尔类型。。。
循环:循环。。。
迭代:迭代。。。
数值类型
数值类型。。。
字符串类型
字符串类型。。。
布尔类型
布尔类型。。。
循环
循环。。。
迭代
迭代。。。
3. 遍历字典
字典可用于以各种方式存储信息,因此有多种遍历字典的方式:可遍历字典的所有键—值对、键或值。
- 遍历所有的键—值对
编写用于遍历字典的for 循环,可声明两个变量,用于存储键—值对中的键和值。对于这两个变量,可使用任何名称。
for 语句的第二部分包含字典名和方法items() ,它返回一个键—值对列表。接下来,for 循环依次将每个键—值对存储到指定的两个变量中。
注意,即便遍历字典时,键—值对的返回顺序也与存储顺序不同。Python不关心键—值对的存储顺序,而只跟踪键和值之间的关联关系。
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " + language.title() + ".")
print("*" * 23)
print("favorite_languages type:{}".format(type(favorite_languages)))
print("favorite_languages.items() type:{}".format(type(favorite_languages.items())))
print("favorite_languages.items():{}".format(favorite_languages.items()))
favorite_languages_items = [('jen', 'python'), ('sarah', 'c'), ('edward', 'ruby'), ('phil', 'python')]
print("favorite_languages_items type:{}".format(type(favorite_languages_items)))
for name, language in favorite_languages_items:
print(name.title() + "'s favorite language is " + language.title() + ".")
执行结果:
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
***********************
favorite_languages type:<class 'dict'>
favorite_languages.items() type:<class 'dict_items'>
favorite_languages.items():dict_items([('jen', 'python'), ('sarah', 'c'), ('edward', 'ruby'), ('phil', 'python')])
favorite_languages_items type:<class 'list'>
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
- 遍历字典中的所有键
字典的keys()返回包含所有键的列表
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
friends = ['phil', 'sarah']
for name in favorite_languages.keys():
print(name.title())
if name in friends:
print(" Hi " + name.title() + ", I see your favorite language is " + favorite_languages[name].title() + "!")
print("favorite_languages.keys():{}".format(favorite_languages.keys()))
print("favorite_languages:{}".format(favorite_languages))
执行结果:
Jen
Sarah
Hi Sarah, I see your favorite language is C!
Edward
Phil
Hi Phil, I see your favorite language is Python!
favorite_languages.keys():dict_keys(['jen', 'sarah', 'edward', 'phil'])
favorite_languages:{'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python'}
遍历字典时,会默认遍历所有的键,因此,如果将上述代码中的for name in favorite_languages.keys(): 替换为for name in favorite_languages: ,输出将不变。
如果显式地使用方法keys() 可让代码更容易理解,你可以选择这样做,但如果你愿意,也可省略它。
方法keys() 并非只能用于遍历;实际上,它返回一个列表。
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
if 'erin' not in favorite_languages.keys():
print("Erin, please take our poll!")
执行结果:
Erin, please take our poll!
字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的(从前面的例子中还真没有体现不可预测???)。
要以特定的顺序返回元素,一种办法是在for 循环中对返回的键进行排序
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.")
执行结果:
Erin, please take our poll!
Edward, thank you for taking the poll.
Jen, thank you for taking the poll.
Phil, thank you for taking the poll.
Sarah, thank you for taking the poll.
- 遍历字典中的所有值
只关注字典中的值,可使用方法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
Ruby
Python
字典的值是可以重复的,所以可以利用集合来过滤数据,来做去重操作!!!
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())
执行结果:
The following languages have been mentioned:
C
Ruby
Python
示例:
languages = {
'数值类型':'数值类型。。。',
'字符串类型':'字符串类型。。。',
'布尔类型':'布尔类型。。。',
'循环': '循环。。。',
'迭代':'迭代。。。',
'条件判断':'条件判断。。。',
'列表':'列表。。。',
'元组':'元组。。。',
'字典':'字典。。。'
}
for language, info in languages.items():
print(language, ":", info)
for language, info in languages.items():
print(language)
print()
print("\t", info)
执行结果:
数值类型 : 数值类型。。。
字符串类型 : 字符串类型。。。
布尔类型 : 布尔类型。。。
循环 : 循环。。。
迭代 : 迭代。。。
条件判断 : 条件判断。。。
列表 : 列表。。。
元组 : 元组。。。
字典 : 字典。。。
数值类型
数值类型。。。
字符串类型
字符串类型。。。
布尔类型
布尔类型。。。
循环
循环。。。
迭代
迭代。。。
条件判断
条件判断。。。
列表
列表。。。
元组
元组。。。
字典
字典。。。
rivers = {
'尼罗河':'埃及',
'长江':'中国',
'多瑙河':'德国'
}
for river in rivers:
# print(type(river))
print(river)
print("*" * 23)
for river in rivers.keys():
# print(type(river))
print(river)
print("*" * 23)
for country in rivers.values():
# print(type(country))
print(country)
执行结果:
尼罗河
长江
多瑙河
***********************
尼罗河
长江
多瑙河
***********************
埃及
中国
德国
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " +
language.title() + ".")
persons=["Sunny", "Denny", "Power", "Paul", "Jeecy", "jen", "sarah", "edward", "phil"]
for person in persons:
if person in favorite_languages.keys():
print('%s,感谢您参与我们的调查!' % person)
else:
print('%s, 邀请您参加我们的调查!' % person)
执行结果:
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
Sunny, 邀请您参加我们的调查!
Denny, 邀请您参加我们的调查!
Power, 邀请您参加我们的调查!
Paul, 邀请您参加我们的调查!
Jeecy, 邀请您参加我们的调查!
jen,感谢您参与我们的调查!
sarah,感谢您参与我们的调查!
edward,感谢您参与我们的调查!
phil,感谢您参与我们的调查!
4.嵌套
列表中嵌套字典
字典中嵌套列表
字典中嵌套字典
4.1 字典列表
aliens = []
# Make 30 green aliens.
for alien_number in range (0,30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
for alien in aliens[0:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 10
elif alien['color'] == 'yellow':
alien['color'] = 'red'
alien['speed'] = 'fast'
alien['points'] = 15
# Show the first 5 aliens:
for alien in aliens[0:5]:
print(alien)
print("...")
print("Total number of aliens: " + str(len(aliens)))
执行结果:
{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'yellow', 'points': 10, 'speed': 'medium'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
...
Total number of aliens: 30
4.2 字典中存储列表
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
# Summarize the order.
print("You ordered a " + pizza['crust'] + "-crust pizza " +
"with the following toppings:")
for topping in pizza['toppings']:
print("\t" + topping)
执行结果:
You ordered a thick-crust pizza with the following toppings:
mushrooms
extra cheese
favorite_languages = {
'jen': ['python', 'ruby'],
'sarah': ['c'],
'edward': ['ruby', 'go'],
'phil': ['python', 'haskell'],
}
for name, languages in favorite_languages.items():
if len(languages) > 0:
if len(languages) == 1:
print("\n" + name.title() + "'s favorite languages is:" + languages[0])
else:
print("\n" + name.title() + "'s favorite languages are:")
for language in languages:
print("\t" + language.title())
else:
print("\n" + name.title() + "'s favorite languages is 0:")
执行结果:
Jen's favorite languages are:
Python
Ruby
Sarah's favorite languages is:c
Edward's favorite languages are:
Ruby
Go
Phil's favorite languages are:
Python
Haskell
列表和字典的嵌套层级不应太多。如果嵌套层级比前面的示例多得多,很可能有更简单的解决问题的方案。
4.3 字典中存储字典
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())
执行结果:
Username: aeinstein
Full name: Albert Einstein
Location: Princeton
Username: mcurie
Full name: Marie Curie
Location: Paris
嵌套的字典的结构都相同,虽然Python并没有这样的要求,但这使得嵌套的字典处理起来更容易。倘若表示每位用户的字典都包含不同的键,for 循环内部的代码将更复杂。
示例:
person1 = {'first_name':'Sunny', 'last_name':'Sun', 'age':38, 'city':'WenZhou'}
person2 = {'first_name':'Denny', 'last_name':'Lv', 'age':42, 'city':'QuZhou'}
person3 = {'first_name':'Power', 'last_name':'Wang', 'age':40, 'city':'ChongQing'}
peoples = [person1, person2, person3]
for people in peoples:
print(people)
print("first_name:\t", people['first_name'])
print("last_name:\t", people['last_name'])
print("age:\t", people['age'])
print("city:\t",people['city'])
print("*" * 23)
执行结果:
{'first_name': 'Sunny', 'last_name': 'Sun', 'age': 38, 'city': 'WenZhou'}
first_name: Sunny
last_name: Sun
age: 38
city: WenZhou
***********************
{'first_name': 'Denny', 'last_name': 'Lv', 'age': 42, 'city': 'QuZhou'}
first_name: Denny
last_name: Lv
age: 42
city: QuZhou
***********************
{'first_name': 'Power', 'last_name': 'Wang', 'age': 40, 'city': 'ChongQing'}
first_name: Power
last_name: Wang
age: 40
city: ChongQing
***********************
rourou = {'name':'rourou', 'type':'鱼类', 'host':'Sunny'}
xiaotuzi = {'name':'xiaotuzi', 'type':'兔子类', 'host':'Denny'}
xiaohonggou = {'name':'xiaohonggou', 'type':'狗类', 'host':'Jeecy'}
pets = [rourou, xiaotuzi, xiaohonggou]
for pet in pets:
for key, value in pet.items():
print("%s:%s" % (key, value))
print("*" * 23)
执行结果:
name:rourou
type:鱼类
host:Sunny
***********************
name:xiaotuzi
type:兔子类
host:Denny
***********************
name:xiaohonggou
type:狗类
host:Jeecy
***********************
favorite_places = {
'Sunny':['新疆', '西藏', '华山'],
'Denny':['香港', '新加坡', '迪拜', '重庆'],
'Power':['马尔代夫', '泰国']
}
for name, places in favorite_places.items():
print(name)
# i = 0
# size = len(places)
# while i < size :
# if i == (size - 1):
# print(places[i])
# else:
# print(places[i], end='、')
# i += 1
# print("*" * 23)
# Better
places.reverse()
while len(places):
if len(places) == 1:
print(places.pop())
else:
print(places.pop(), end='、')
print("*" * 23)
执行结果:
Sunny
新疆、西藏、华山
***********************
Denny
香港、新加坡、迪拜、重庆
***********************
Power
马尔代夫、泰国
***********************
luck_num = {
'Sunny':[23, 3, 7, 24, 6, 12],
'Denny':[24, 9, 6],
'Jeecy':[69, 12],
'Power':[62, 2],
'Paul':[7, 15]
}
for name, nums in luck_num.items():
print(name)
for num in nums:
print(num)
print("*" * 23)
执行结果:
Sunny
23
3
7
24
6
12
***********************
Denny
24
9
6
***********************
Jeecy
69
12
***********************
Power
62
2
***********************
Paul
7
15
***********************
cities = {
'上海':{'country':'中国', 'population':'100w', 'fact':'中国金融中心'},
'巴黎':{'country':'法国', 'population':'99w', 'fact':'文艺复兴'},
'纽约':{'country':'美国', 'population':'150w', 'fact':'美帝。。。'}
}
for city, info in cities.items():
print(city)
for key, value in info.items():
print('%s:%s' % (key, value))
print("*" * 23)
执行结果:
上海
country:中国
population:100w
fact:中国金融中心
***********************
巴黎
country:法国
population:99w
fact:文艺复兴
***********************
纽约
country:美国
population:150w
fact:美帝。。。
***********************