{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 获取字典值"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"字典是一种无序序列类型,不能使用<font color='red'>**序号索引**</font>的方式获取字典的值。 \n",
"字典内部的数据具有“键”和“值”的映射关系,字典一般通过<font color='red'>**“键”**</font>来访问其“值”。 \n",
"根据键值查询字典中的元素的速度很快,这是基于字典巨大的内存开销获得的,属于典型的空间换时间。 \n",
"\n",
"语法为:\n",
"```python\n",
"dict[key]\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 实例 6.4 通讯录查询"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"构建一个字典,存储姓名和对应的电话号码\n",
"```python\n",
"{'李明': '13988887777', '张宏': '13866668888', '吕京': '13143211234'}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"利用这个字典开发一个简单的通讯录程序。具备简单的查询、更新、插入、删除等功能。\n",
"\n",
"本节先实现查询的功能,实现输入一个姓名,查询对应的电话号码的功能。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/26.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"请输入要查询的联系人姓名: 黎明\n"
]
},
{
"ename": "KeyError",
"evalue": "'黎明'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m/tmp/ipykernel_395/3945917760.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# 索引方法实现查询功能\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mname\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'请输入要查询的联系人姓名:'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\":\"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mphonebook_dict\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 以输入的人名为键访问字典中该键对应的值\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mKeyError\u001b[0m: '黎明'"
]
}
],
"source": [
"# 用字典存储数据的通讯录程序,查询功能\n",
"phonebook_dict = {'李明': '13988887777', '张宏': '13866668888', '吕京': '13143211234'}\n",
"\n",
"# 索引方法实现查询功能\n",
"name = input('请输入要查询的联系人姓名:')\n",
"print(name + \":\" + phonebook_dict[name]) # 以输入的人名为键访问字典中该键对应的值"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"使用dict[key]方法时,若字典中<font color='red'>**不存在该键**</font>,程序会抛出<font color='red'>**KeyError异常**</font>。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(name + \":\" + phonebook_dict['李小明']) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"为了避免在字典中取数据时出现访问不存在的键值导致的异常,使程序运行意外中止,可以<font color='red'>**先判断键是否存在**</font>,或使用异常处理。\n",
"\n",
"修改后的完整实现代码如下:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"请输入要查询的联系人姓名: 黎明\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"联系人不存在\n"
]
}
],
"source": [
"def query(name):\n",
" # 索引方法实现查询功能\n",
" if name in phonebook_dict: # 为避免姓名不存在导致异常,先判断是否存在\n",
" return name + \":\" + phonebook_dict[name] # 以输入的人名为键访问字典中该键对应的值\n",
" else:\n",
" return \"联系人不存在\"\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" # 用字典存储数据的通讯录程序,查询功能\n",
" phonebook_dict = {'李明': '13988887777', '张宏': '13866668888', '吕京': '13143211234'}\n",
" Name = input('请输入要查询的联系人姓名:')\n",
" print(query(Name))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"除此之外,还可以使用字典的内置方法<font color='red'>**get()**</font>来获取数据,其语法为:\n",
"```python\n",
"dict.get(k[, default])\n",
"```\n",
"字典dict中**存在以“k”为键的元素时,则返回值该键对应的值**。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"13988887777\n"
]
}
],
"source": [
"print( phonebook_dict.get('李明')) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"当字典dict中**不存在以“k”为键的元素**时,如果**没有提供 default 参数**,则**返回空值 None**。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"None\n"
]
}
],
"source": [
"print(phonebook_dict.get('李小明')) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"当字典dict中**不存在以“k”为键的元素**时,如果**提供了 default 参数**,则**返回default**。"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"print(phonebook_dict.get('李小明', '联系人不存在'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"建议在获取字典值时,尽可能使用<font color='red'>**字典的get()方法**</font>,可以避免键不存在时引发的错误。 \n",
"用get()方法修改后的完整代码如下:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"def query(name):\n",
" # get()方法实现查询功能\n",
" return name + \":\" + phonebook_dict.get(name, '联系人不存在') \n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" # 用字典存储数据的通讯录程序,查询功能\n",
" phonebook_dict = {'李明': '13988887777', '张宏': '13866668888', '吕京': '13143211234'}\n",
" Name = input('请输入要查询的联系人姓名:')\n",
" print(query(Name))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 根据年月查询该月天数"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def leap(year: int) -> bool:\n",
" \"\"\"接收一个表示年份的整数,判定是否是闰年,返回布尔值 \"\"\"\n",
" return year % 400 == 0 or (year % 4 == 0 and year % 100 != 0)\n",
"\n",
"\n",
"def days_of_month(month: int, year: int) -> int:\n",
" \"\"\"接收一个表示月份的整数,返回该月的天数\"\"\"\n",
" days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n",
" days_dic = dict(zip(range(1, 13), days_of_month)) # 构建每月天数字典\n",
" days = days_dic.get(month) # 查询本月天数\n",
" if leap(year) and month == 2:\n",
" days = days + 1 # 若为闰年2月,该月为29天\n",
" return days\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" today = input() # 输入8位的年月日\n",
" year = int(today[:4])\n",
" month = int(today[4:6])\n",
" print(days_of_month(month, year))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"字典提供了内置方法<font color='red'>**keys()**</font>、<font color='red'>**values()**</font>和<font color='red'>**items()**</font>可以获取字典中所有的<font color='red'>**“键”**</font>、<font color='red'>**“值”**</font>和<font color='red'>**“键-值”对**</font>的视图。 \n",
"返回值是一个<font color='red'>**可迭代对象**</font>,其中的<font color='red'>**数据顺序确定**</font>,数据顺序与加入顺序相同。 \n",
"获取视图方法的描述如下表所示。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"| 方法 | 描述 |\n",
"| :------------- | :------------------------------------------------------------ |\n",
"| dict.keys() | 获取字典dict中的所有键组成一个可迭代数据对象。 |\n",
"| dict.values() | 获取字典dict中的所有值组成一个可迭代数据对象。 |\n",
"| dict.items() | 获取字典dict中的所有键值对,两两组成元组,形成一个可迭代数据对象。 |"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"phonebook_dict = {'李明': '13988887777', '张宏': '13866668888', '吕京': '13143211234'}\n",
"# 返回可迭代对象,dict_keys(['李明', '张宏', '吕京'])\n",
"keys = phonebook_dict.keys()\n",
"# 返回可迭代对象,dict_values(['13988887777', '13866668888', '13143211234'])\n",
"values=phonebook_dict.values()\n",
"# 返回可迭代对象,dict_items([('李明', '13988887777'), ('张宏', '13866668888'), ('吕京', '13143211234')])\n",
"key_value_pairs=phonebook_dict.items() \n",
"print(keys) \n",
"print(values) \n",
"print(key_value_pairs) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/27.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"上述3种方法返回值是<font color='red'>**可迭代数据对象**</font>,可对其进行<font color='red'>**遍历**</font>或用<font color='red'>**list()将其转为列表**</font>。"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"phonebook_dict = {'李明': '13988887777', '张宏': '13866668888', '吕京': '13143211234'}\n",
"keys = list(phonebook_dict.keys())\n",
"print(keys)\n",
"for name in keys: #对可迭代对象dict_keys()进行遍历输出\n",
" print(name)\n",
"for name,phone in phonebook_dict.items(): #对可迭代对象dict.items()进行遍历输出\n",
" print(name+':'+phone)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在 Python 3.7 版以后,字典顺序会确保为插入顺序,所以这3个方法的返回值也都是有序数据,可以使用sorted()等应用于序列的方法对其进行操作。\n",
"但向.往中烈面添元素新键可能导致,使导致散列表中的键的次序发生。化.,此,不要在遍历字典的同时对进行典的。改."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"city = {'北京': 1961, '重庆': 2885, '成都': 1405, '上海': 2302}\n",
"city_name = list(city.keys()) # ['重庆', '上海', '北京', '成都']\n",
"total_population = sum(city.values()) # 可迭代对象可以直接做sum()的参数\n",
"print(f'城市列表:{city_name}') # 城市列表:['重庆','上海','北京','成都']\n",
"print(f'城市人口{total_population}万人') # 城市人口8553万人\n",
"print(sorted(city.values())) # 排序输出[1405, 1961, 2302, 2885]\n",
"print(sorted(city.items(), key=lambda x:x[1])) # 排序输出[('成都', 1405), ('北京', 1961), ('上海', 2302), ('重庆', 2885)]"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}