{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 修改字典值"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"字典是一种可变的数据类型,支持数据元素的增加、删除和修改操作。仍以通讯录为例,在使用的过程中,可能需要向数据里插入新的联系人数据、更新原有的联系人的姓名或电话、删除其中的数据。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 元素值的修改与新增"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用dict\\[key\\] = value方法"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**当键名key在字典中存在时,将修改字典dict中键key的值为新值value;**\n",
"\n",
"**当键名key在字典中不存在时,将为字典增加以key为键,以value为值的新元素。**"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'李明': '13988887788', '张宏': '13866668888', '赵雪': '13000112222'}\n"
]
}
],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"# 键存在时更新\n",
"tel_book['李明'] = '13988887788' # 李明的电话更新为 '13988887788'\n",
"tel_book['赵雪'] = '13000112222' #新增元素 '赵雪': '13000112222'\n",
"print(tel_book) # {'李明': '13988887788', '张宏': '13866668888', '赵雪': '13000112222'}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/1.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用dict.update(k1=v1[, k2=v2,…])方法"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**可以用dict.update(k1=v1[, k2=v2,…])方法同时更新字典中的多个值:**\n",
"\n",
"**当字典dict中存在k1、k2…时,将对应的值修改为v1、v2…;**\n",
"\n",
"**当不存在相应的键值时,会将对应的k1:v1、k2:v2…键值对加入字典。**"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'李明': '13988887777', '张宏': '13866668877', '王晶': '13244441111'}\n"
]
}
],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"# 将张宏的电话更新为'13866668877' ;'王晶'不存在,以键值对形式加入到字典中\n",
"tel_book.update(张宏='13866668877', 王晶='13244441111') \n",
"print(tel_book) # {'李明': '13988887777', '张宏': '13866668877', '王晶': '13244441111'}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/2.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用dict.update(\\[other\\])方法"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**接受另一个字典对象,或者一个包含键/值对(以长度为二的元组或其他可迭代对象表示)的可迭代对象。**\n",
"\n",
"**当other中的键在字典dict中存在时,将修改为对应的值;**\n",
"\n",
"**当other中的键在字典dict中不存在时,将键值对加入字典dict。**"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'李明': '13988887788', '张宏': '13866668888', '程钱': '13111223214'}\n"
]
}
],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"tel_book2 = {'李明': '13988887788', '程钱': '13111223214'}\n",
"tel_book.update(tel_book2)\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/3.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"tel_book2 = [('李明', '13988887788'), ('程钱', '13111223214')]\n",
"tel_book.update(tel_book2) # 也可使用包含键/值对(以长度为二的元组或其他可迭代对象表示)的可迭代对象\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/4.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用dict.setdefault(key[, value])方法"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**当字典dict 中存在键key时,返回key对应的值;**\n",
"\n",
"**键key不存在时,在字典中增加 key: value 键值对,值value缺省时,默认设其值为None。**"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"tel_book.setdefault('刘飞','13344556655') # 为字典新增元素 '刘飞': '13344556655'\n",
"tel_book.setdefault(('程钱')) # 值缺省时,默认为None,为字典新增元素'程钱': None\n",
"print(tel_book)\n",
"phone_number = tel_book.setdefault('李明') # 存在键'李明',返回其值'13988887777'\n",
"print(phone_number)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/5.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (993078169.py, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"/tmp/ipykernel_173/993078169.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m + ### 使用运算符“|”和 “|=”\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"+ ### 使用运算符“|”和 “|=”"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Python 3.9 以后版本新增**\n",
"\n",
"**d | other:合并 d 和 other 中的键和值来创建一个新的字典,两者必须都是字典。当 d 和 other 有相同键时, other 的值优先。**\n",
"\n",
"**d |= other:用 other 的键和值更新字典 d ,other 可以是字典或可迭代的键值对。当 d 和 other 有相同键时, other 的值优先。**"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"tel_book2 = {'刘飞': '13344556655', '程钱': '13111223214'}\n",
"tel = tel_book | tel_book2\n",
"print(tel)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/6.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"tel_book2 = {'刘飞': '13344556655', '程钱': '13111223214'}\n",
"tel_book |= tel_book2 \n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/7.png\" style=\"zoom:50%;\">\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 字典元素的删除\n",
"\n",
"+ ### 使用dict.pop(key[, default])方法\n",
"\n",
"**将键为 key 的键值对元素删除,返回值为键 key 对应的值;**\n",
"\n",
"**如果提供了default 值,dict 中不存在 key 键时返回 default,否则将会触发“KeyValue”异常。**\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"del_key = tel_book.pop('张宏')\n",
"print('删除的联系人的电话是:', del_key)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/8.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"del_key = tel_book.pop('李宏', '用户不存在')\n",
"print('删除的联系人的电话是:', del_key)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/9.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"del_key = tel_book.pop('李宏') # 未设置default 值,将会触发“KeyValue”异常\n",
"print('删除的联系人的电话是:', del_key)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用dict.popitem()方法\n",
"\n",
"**从字典中移除并返回一个元组形式的(键, 值) 对,**\n",
"\n",
"**键值对会按LIFO(Last In, First Out, 后进先出)顺序被返回,即每次执行删除位于字典末尾的键值对。**\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"delitem = tel_book.popitem() \n",
"print('删除的联系人是:',delitem)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/10.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"如果字典为空,调用 popitem() 将引发 KeyError。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {}\n",
"delitem = tel_book.popitem() \n",
"print('删除的联系人是:',delitem)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用dict.clear()方法\n",
"\n",
"**清空字典dict中所有数据,保留空字典对象。**"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"tel_book.clear() # 清空字典中的所有数据\n",
"print(tel_book) # {}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/11.png\" style=\"zoom:50%;\">\n",
"\n",
"+ ### 使用del dict[key]指令\n",
"\n",
"**将字典dict中键为key的键值对元素删除,如果不存在键key则会引发 KeyError。**"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"del tel_book['张宏'] # 删除键为'张宏'的键值对\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/12.png\" style=\"zoom:50%;\">"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"del tel_book['李小明'] # 键'李小明'不存在,引发KeyError\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"+ ### 使用del dict指令\n",
"\n",
"**将字典对象dict删除,后续如果再次引用该对象将引发NameError。**"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"del tel_book # 删除名为tel_book的字典对象\n",
"print(tel_book) # 触发NameError异常"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### “视图”可迭代数据\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"使用字典keys()、values()和items()方法生成的可迭代数据是一种特殊的“视图”类数据,这三个方法可以分别获得一个包含字典全部键、值和键值对的对象。 \n",
"它们的值关联至原始字典,<font color='red'>**当原始字典中的数据发生改变时,其值也会发生变化**</font>。"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"ks = tel_book.keys()\n",
"vs = tel_book.values()\n",
"kvs = tel_book.items()\n",
"print(ks) # dict_keys(['李明', '张宏'])\n",
"print(vs) # dict_values(['13988887777', '13866668888'])\n",
"print(kvs) #dict_items([('李明', '13988887777'), ('张宏', '13866668888')])\n",
"tel_book.update(王晶='13244441111') #键‘王晶’不存在,将键值对加入字典\n",
"print(tel_book) #{'李明': '13988887777', '张宏': '13866668888', '王晶': '13244441111'}\n",
"print(ks) #print(ks) dict_keys(['李明', '张宏', '王晶'])\n",
"print(vs) #dict_values(['13988887777', '13866668888', '13244441111'])\n",
"print(kvs) #dict_items([('李明', '13988887777'), ('张宏', '13866668888'), ('王晶', '13244441111')])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"images/ch7/long/13.png\" style=\"zoom:50%;\">\n",
"\n",
"Python 3.7版之后:,字典顺序会确保为插入顺序,因此这三个方法的返回值也按插入顺序,可以进行如下相关操作。"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888'}\n",
"ks = tel_book.keys()\n",
"vs = tel_book.values()\n",
"kvs = tel_book.items()\n",
"print(len(kvs)) # 可使用len()函数获取元素个数\n",
"print(list(zip(ks, vs))) # 允许使用zip()来创建 (值, 键) 对\n",
"print([(k, v) for (k, v) in kvs]) # 允许使用推导式来创建 (值, 键) 对\n",
"print(('李明', '13988887777') in kvs) # 支持成员检测\n",
"print(list(reversed(kvs))) # 支持逆序,返回一个逆序获取字典键、值或项的迭代器。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"遍历字典时,若字典元素被删除,会导致字典长度发生变化而导致异常:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 删除字典中特定元素"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888', '李小明': '13988886666', '李广': '13988885555', }\n",
"\n",
"# 删除字典中姓“李”的人的元素\n",
"for user_name in tel_book: # RuntimeError: dictionary changed size during iteration\n",
" if user_name[0] == '李':\n",
" tel_book.pop(user_name)\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"因字典的视图会随字典元素变化而发生变化,所以也不可以通过遍历字典视图的方法删除字典中的元素。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888', '李小明': '13988886666', '李广': '13988885555', }\n",
"\n",
"# 删除字典中姓“李”的人的元素\n",
"for user_name in tel_book.keys(): # RuntimeError: dictionary changed size during iteration\n",
" if user_name[0] == '李':\n",
" tel_book.pop(user_name)\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"为避免这个问题,推荐两个方法:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 将字典的视图转为列表再用于控制遍历:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888', '李小明': '13988886666', '李广': '13988885555', }\n",
"\n",
"# 删除字典中姓“李”的人的元素\n",
"for user_name in list(tel_book.keys()): # RuntimeError: dictionary changed size during iteration\n",
" if user_name[0] == '李':\n",
" tel_book.pop(user_name)\n",
"print(tel_book)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 通过字典推导式的方法创建新的字典:\n",
"新字典元素是删除是过滤掉特定元素后的结果"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888', '李小明': '13988886666', '李广': '13988885555', }\n",
"# 删除字典中姓“李”的人的元素\n",
"tel_book_new = {x[0]: x[1] for x in tel_book.items() if x[0][0] != '李'}\n",
"print(tel_book_new) # {'张宏': '13866668888'}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 建议遍历时,直接用两个变量,可避免索引的使用,使程序更容易理解:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tel_book = {'李明': '13988887777', '张宏': '13866668888', '李小明': '13988886666', '李广': '13988885555', }\n",
"# 删除字典中姓“李”的人的元素\n",
"tel_book_new = {k: v for k, v in tel_book.items() if k[0] != '李'}\n",
"print(tel_book_new) # {'张宏': '13866668888'}"
]
}
],
"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
}