在这篇文章中,我们将为您详细介绍跟踪python中列表和字典的更改?的内容,并且讨论关于跟踪python中列表和字典的更改命令的相关问题。此外,我们还会涉及一些关于20190513——python基础
在这篇文章中,我们将为您详细介绍跟踪python中列表和字典的更改?的内容,并且讨论关于跟踪python中列表和字典的更改命令的相关问题。此外,我们还会涉及一些关于20190513——python基础(列表、数据类型:字典、列表和字典的异同)、copy()——python中列表和字典的深拷贝与浅拷贝、Python 列表和字典常踩坑即解决方案、Python 列表和字典有什么不同之处?Python 学习资料!的知识,以帮助您更全面地了解这个主题。
本文目录一览:- 跟踪python中列表和字典的更改?(跟踪python中列表和字典的更改命令)
- 20190513——python基础(列表、数据类型:字典、列表和字典的异同)
- copy()——python中列表和字典的深拷贝与浅拷贝
- Python 列表和字典常踩坑即解决方案
- Python 列表和字典有什么不同之处?Python 学习资料!
跟踪python中列表和字典的更改?(跟踪python中列表和字典的更改命令)
我有一个此类的实例需要跟踪其属性更改的类。
例如:obj.att = 2
将东西是很容易可追踪通过简单地重写__setattr__
的obj
。
但是,当我要更改的属性是对象本身(如列表或字典)时,就会出现问题。
我将如何跟踪类似obj.att.append(1)
或的信息obj.att.pop(2)
?
我正在考虑扩展列表或字典类,但是一旦obj
和obj.att
都被初始化,猴子会修补这些类的实例,以便obj
在.append
调用诸如此类的东西时得到通知。不知何故,那感觉并不十分优雅。
我能想到的另一种方法是将实例传递obj
到列表初始化中,但这会破坏很多现有代码,而且看起来甚至比以前的方法还不够优雅。
还有其他想法/建议吗?我在这里缺少一个简单的解决方案吗?
20190513——python基础(列表、数据类型:字典、列表和字典的异同)
二、python基础(列表、数据类型:字典、列表和字典的异同)
1、列表
1)什么是列表
2)从列表提取单个元素
# 偏移量。列表中的各个元素,好比教室里的某排学生那样,是有序地排列的,也就是说,每个元素都有自己的位置编号(即偏移量)。
# 1.偏移量是从0开始的,而非我们习惯的从1开始;2.列表名后加带偏移量的中括号,就能取到相应位置的元素。
students = [''小九'',''小八'',''小七'',''小六'',''小五'',''小四'',''小三'',''老二'',''老大'']
print(students[3])
>>>小六


students = [''小九'',''小八'',''小七'',''小六'',''小五'',''小四'',''小三'',''老二'',''老大'']
print(students[3])
# 提取字典中的第三个元素,从0开始数,往右数第三个元素:“小六”
# >>>小六
3)从列表提取多个元素
# 这种用冒号来截取列表元素的操作叫作切片,顾名思义,就是将列表的某个片段拿出来处理。这种切片的方式可以让我们从列表中取出多个元素。
list2 = [5,6,7,8,9]
print(list2[:])
# 打印出[5, 6, 7, 8, 9]
print(list2[2:])
# 打印出[7, 8, 9]
print(list2[:2])
# 打印出[5, 6]
print(list2[1:3])
# 打印出[6, 7]
print(list2[2:4])
# 打印出[7, 8]
# 列表切片口诀:冒号左边空,就要从偏移量为0的元素开始取;右边空,就要取到列表的最后一个元素。后半句:冒号左边数字对应的元素要拿,右边的不动(可再回顾下代码)。
# 偏移量取到的是列表中的元素,而切片则是截取了列表的某部分,所以还是列表
students = [''小九'',''小八'',''小七'',''小六'',''小五'',''小四'',''小三'',''老二'',''老大'']
print(students[2:4])
print(students[2])
>>>[''小七'', ''小六'']
小七
4)给列表增加/删除元素
增加元素
# 请运行以下代码:报错后,可读一下报错信息,然后将第6行注释掉再运行。
list3 = [1,2]
list3.append(3)
# 注意格式是:列表名.append()
# append后的括号里只能接受一个参数
print(list3)
#list3.append(4,5)
list3.append([4,5])
# append函数并不生成一个新列表,而是让列表末尾新增一个元素。而且,列表长度可变,理论容量无限,所以支持任意的嵌套。
print(list3)
>>>[1, 2, 3]
[1, 2, 3, [4, 5]]
删除元素
students = [''小明'',''小红'',''小刚'',''小美'']
del students[1]
print(students)
>>>[''小明'', ''小刚'', ''小美'']
# del语句非常方便,既能删除一个元素,也能一次删除多个元素(原理和切片类似,左取右不取)。
2、字典
1)什么是字典
# 字典和列表有3个地方是一样的:1.有名称;2.要用=赋值;3.用逗号作为元素间的分隔符。
# 而不一样的有两处:1.列表外层用的是中括号[ ],字典的外层是大括号{ };2.列表中的元素是自成一体的,而字典的元素是由一个个键值对构成的,用英文冒号连接。如''小明'':95,其中我们把''小明''叫键(key),95叫值(value)。
students = [''小明'',''小红'',''小刚'']
scores = {''小明'':95,''小红'':90,''小刚'':90}
# 唯一的键和对应的值形成的组合,我们就叫做【键值对】,上述字典就有3个【键值对】:''小明'':95、''小红'':90、''小刚'':90
# 强调:字典中的键具备唯一性,而值可重复。也就是说字典里不能同时包含两个''小明''的键,但却可以有两个同为90的值。
# 如果不想口算,我们可以用len()函数来得出一个列表或者字典的长度(元素个数),括号里放列表或字典名称。
students = [''小明'',''小红'',''小刚'']
scores = {''小明'':95,''小红'':90,''小刚'':90}
print(len(students))
print(len(scores))
>>>3
3
2)从字典中提取元素
# 字典的索引,和列表通过偏移量来索引不同,字典靠的是键。
scores = {''小明'': 95, ''小红'': 90, ''小刚'': 90}
print(scores[''小明''])
>>>95
# 这便是从字典中提取对应的值的用法。和列表相似的是要用[ ],不过因为字典没有偏移量,所以在中括号中应该写键的名称,即字典名[字典的键]。
3)给字典增加/删除元素
album = {''周杰伦'':''七里香'',''王力宏'':''心中的日月''}
del album[''周杰伦'']
print(album)
album[''周杰伦''] = ''十一月的萧邦''
print(album)
print(album[''周杰伦''])
>>>
{''王力宏'': ''心中的日月''}
{''王力宏'': ''心中的日月'', ''周杰伦'': ''十一月的萧邦''}
十一月的萧邦
# 删除字典里键值对的代码是del语句del 字典名[键],而新增键值对要用到赋值语句字典名[键] = 值。
3、列表和字典的异同
1)不同点:
- 列表有序,要用偏移量定位;字典无序,便通过唯一的键来取值。
- 列表中的元素是有自己明确的“位置”的,所以即使看似相同的元素,只要在列表所处的位置不同,它们就是两个不同的列表。我们来看看代码:
# 如果==左右两边相等,值为True,不相等则为False。
print(1 == 1)
# 1等于1,所以值为True
print(1 == 2)
# 1不等于2,所以为False
students1 = [''小明'',''小红'',''小刚'']
students2 = [''小刚'',''小明'',''小红'']
print(students1 == students2)
scores1 = {''小明'':95,''小红'':90,''小刚'':100}
scores2 = {''小刚'':100,''小明'':95,''小红'':90}
print(scores1 == scores2)
>>>
True
False
False
True
2)共同点:
- 在列表和字典中,如果要修改元素,都可用赋值语句来完成。看一下代码:
list1 = [''小明'',''小红'',''小刚'',''小美'']
list1[1] = ''小蓝''
print(list1)
dict1 = {''小明'':''男''}
dict1[''小明''] = ''女''
print(dict1)
>>>[''小明'', ''小蓝'', ''小刚'', ''小美'']
{''小明'': ''女''}
- 支持任意嵌套。除之前学过的数据类型外,列表可嵌套其他列表和字典,字典也可嵌套其他字典和列表。
# 列表提取元素
students = [[''小明'',''小红'',''小刚'',''小美''],[''小强'',''小兰'',''小伟'',''小芳'']]
print(students[1][3])
>>>小芳
# 字典提取键
scores = {
''第一组'':{''小明'':95,''小红'':90,''小刚'':100,''小美'':85},
''第二组'':{''小强'':99,''小兰'':89,''小伟'':93,''小芳'':88}
}
print(scores[''第二组''][''小芳''])
>>>88
# 列表和字典嵌套的情况下,提取元素:
students = {
''第一组'':[''小明'',''小红'',''小刚'',''小美''],
''第二组'':[''小强'',''小兰'',''小伟'',''小芳'']
}
scores = [
{''小明'':95,''小红'':90,''小刚'':100,''小美'':85},
{''小强'':99,''小兰'':89,''小伟'':93,''小芳'':88}
]
print(students[''第一组''][2])
print(scores[0][''小刚''])
>>>小刚
100
作业:
1、
# 把列表list1中的''love''取出来,并打印出来。
list1 = [{''嫉妒'':''envy''},{''恨'':''hatred''},{''爱'':''love''}]
print(list1[2][''爱''])
print(list1[1][''恨''])
# 把字典dict1中的''love''取出来,并打印出来。
dict1 = {1:[''cake'',''scone'',''puff''],2:[''London'',''Bristol'',''Bath''],3:[''love'',''hatred'',''envy'']}
print(dict1[3][0])
# 提取A
tuple1 = (''A'',''B'')
list2 = [(''A'',''B''),(''C'',''D''),(''E'',''F'')]
print(tuple1[0])
print(list2[0][0])
>>>
love
hatred
love
A
A
2、
# 请你通过所学知识,把列表中的“狼”取出来,并打印出来。
townee = [
{''海底王国'':[''小美人鱼''''海之王''''小美人鱼的祖母''''五位姐姐''],''上层世界'':[''王子'',''邻国公主'']},
''丑小鸭'',''坚定的锡兵'',''睡美人'',''青蛙王子'',
[{''主角'':''小红帽'',''配角1'':''外婆'',''配角2'':''猎人''},{''反面角色'':''狼''}]
]
print(townee[5][1][''反面角色''])
>>>
狼
copy()——python中列表和字典的深拷贝与浅拷贝
在Python中,把列表,字典对象赋值给变量时,都是“浅拷贝”,即,变量指向了对象,原来的对象改变了,这个变量的值也会跟着变。而cop()函数是“深拷贝”,重新创造一个新对象赋值给变量,原来的对象的改变不影响新对象。搞清楚深拷贝与浅拷贝有利于避免很多错误
类比C语言中的指针,把d1比作指针,使用’d2=d1‘语句对字典名d1进行浅拷贝就好比只是创建了另外一个指向d1的指针d2,d2和d1指向的都是同一段数据,而使用copy()方法后的’d3 = d1.copy()‘,相当于又重新申请了一段内存用来把d1指向的数据复制过来,个人见解,如果错误了请批评指正
具体代码示例如下所示:
1 d1 = {''a'':1}
2
3 d2 = d1 # 浅拷贝
4 d3 = d1.copy() # 深拷贝
5
6 d1[''a''] = 2 # 改变原来的字典
7
8 print(''d1='',d1)
9 print(''d2='',d2)
10 print(''d3='',d3)
11
12
13 """
14 输出结果如下:
15 d1= {''a'': 2}
16 d2= {''a'': 2}
17 d3= {''a'': 1}
18 """
Python 列表和字典常踩坑即解决方案
前言:
在Python中,如果我们想要在遍历一组数据的过程中,对这组数据进行修改,通常会出现许多问题,例如对列表进行上述操作时, 会忽略部分数据;遍历字典时,不能修改数据。本文针对这些问题,提出了多种解决方案。
一、关于列表
1.问题描述
在Python中,如果你试图在遍历一组数据的过程中,对其进行修改,这通常没什么问题。
例如:
l = [3, 4, 56, 7, 10, 9, 6, 5] for i in l: if not i % 2 == 0: continue l.remove(i) print(l)
上述这段代码遍历了一个包含数字的列表,为了去除掉所有偶数,直接修改了列表l。
然而,运行后输出却是:
[3, 56, 7, 9, 5]
等一下!输出似乎不对。最终的结果仍然含有一个偶数56。为什么没有成功去除这个数呢?我们可以尝试打印出 for循环遍历的所有元素,
运行如下代码:
l = [3, 4, 56, 7, 10, 9, 6, 5] for i in l: print(i) if not i % 2 == 0: continue l.remove(i) print(l)
这段代码的输出为:
3
4
7
10
6
[3, 56, 7, 9, 5]
从输出可以看出,for循环似乎没有访问列表中的所有元素。为了解for循环在内部究竟做了什么, 我们可以使用 iter 和 next 来模拟一下。
看看下面这个例子,我使用了ipython shell 来运行代码:
In [1]: l = [3, 4, 56, 7, 10, 9, 6, 5] In [2]: # 把列表变成一个迭代器 In [3]: it = iter(l) In [4]: # 使用 next() 方法来模拟 for循环 In [5]: next(it) Out[5]: 3 In [6]: next(it) Out[6]: 4 In [7]: # 移除一个迭代器已经访问过的元素 In [8]: l.remove(3) In [9]: next(it) Out[9]: 7 In [10]: # 注意此处跳过了56,我们可以再移除一个元素 In [11]: l.remove(4) In [12]: next(it) Out[12]: 9
上面这个实验揭示了:当你移除一个迭代器已经访问过的元素后,在下一次迭代时,会跳过右边的一个元素,直接访问下一个。
反之依然成立,即当开始迭代后,如果你在列表开头添加了一个元素,下次迭代时,可能会访问到已经迭代过的元素,
下面这段代码就出现了这种情况:
In[1]: l = [3, 4, 56, 7, 10, 9, 6, 5] In[2]: it = iter(l) In[3]: next(it) Out[3]: 3 In[4]: next(it) Out[4]: 4 In[5]: l.insert(0, 44) In[6]: next(it) Out[6]: 4
注意:当在列表头部添加了44后,4被访问了两次。
2.解决方案
为了解决上述问题,我们必须得确保:不能移除迭代器访问过的元素。
方案一
我们可以先对原列表进行翻转得到一个新列表,再对新列表进行迭代,并在原列表 l 中移除不符合条件的元素。
该方案代码如下:
l = [3, 4, 56, 7, 10, 9, 6, 5] # 迭代翻转后的列表 for i in reversed(l): print(i) if not i % 2 == 0: continue l.remove(i) print(l)
结果如下:
5
6
9
10
7
56
4
3
[3, 7, 9, 5]
注意:迭代器现在成功访问到了列表中的所有元素,并最终输出了只含有奇数的列表。
方案二
我们还可以在开始迭代前,先复制列表 l 。但是当列表 l 中的数据过多时,这样做显然比较耗费性能。
该方案代码如下:
l = [3, 4, 56, 7, 10, 9, 6, 5] # 在这里使用 ''l.copy()'' 来对列表 l 进行浅拷贝 for i in l.copy(): print(i) if not i % 2 == 0: continue l.remove(i) print(l)
输出如下:
3
4
56
7
10
9
6
5
[3, 7, 9, 5]
该方案能保证迭代的顺序和移除元素的顺序相同。不过由于迭代和移除这两种操作针对的是两个不同的列表,因此顺序相同并不重要。
二、关于字典
1.问题描述
在对字典进行迭代时,不能修改字典。如下:
# {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} d = {k: k for k in range(10)} for k, v in d.items(): if not v % 2 == 0: continue d.pop(k)
这段代码会产生 RuntimeError :
Traceback (most recent call last): File "F:/Documents/pythonprojects/01practice/app.py", line 7, in <module> for k, v in d.items(): RuntimeError: dictionary changed size during iteration
2.解决方案
我们可以先复制字典的所有 key ,随后在迭代 key 的过程中,移除不符合条件的元素。过程如下:
# {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} d = {k: k for k in range(10)} # 这里复制了字典中的所有key值 # 没有复制整个字典 # 同时使用tuple()速度更快 for k in tuple(d.keys()): if not d[k] % 2 == 0: continue d.pop(k) print(d)
运行代码后输出如下:
{1: 1, 3: 3, 5: 5, 7: 7, 9: 9}
我们成功移除了字典中的所有偶数键值对!
结论
文中我们针对迭代一组数据时无法进行修改的问题,分别提出了不同的解决方案:如果想在遍历列表的时候,对列表进行修改, 我们可以先对原列表进行翻转或复制,从而得到一个新列表,随后在遍历新列表的过程中,修改原列表中的数据;如果我们想在遍历字典的时候,对字典进行修改,可以先复制字典的所有键值,然后在迭代键值的时候,修改字典中的数据。
到此这篇关于 Python 列表和字典常踩坑即解决方案的文章就介绍到这了,更多相关 Python 列表和字典 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
- python 如何读取列表中字典的value值
- Python 列表推导式与字典推导式的实现
- python中字典和列表的相互嵌套问题详解
- python 列表,集合和字典的增删改查
- Python编程根据字典列表相同键的值进行合并
- python 字典和列表嵌套用法详解
Python 列表和字典有什么不同之处?Python 学习资料!

Python 数据类型分为七大类,其中最为常见的就是列表和字典,是使用 Python 必须掌握的基础。那么 Python 列表和字典有什么不同之处?我们一起来看看吧。
列表
1. 任意对象的有序集合,列表是一组任意类型的值,按照一定顺序组合而成的;
2. 通过偏移读取,组成列表的值叫做元素,每一个元素被标识一个索引,第一个索引是 0,序列的功能都能实现;
3. 可变长度,异构以及任意嵌套,列表中的元素可以是任意类型,甚至是列表类型,也可以说列表可以嵌套;
4. 可变的序列,支持索引、切片、合并、删除等操作,都是在原处进行修改列表;
5. 对象引用数组,列表可以当成普通的数组,每当用到引用时,Python 总是会将这个引用指向对象,所以程序无需处理对象的操作。当把一个对象赋给一个数据结构元素或变量名时,Python 总是会存储对象的引用,而不是对象的拷贝。
字典
1. 字典就是一个关联数组,是一个通过关键字索引的对象的集合,使用键 - 值进行存储,查找速度快;
2. 字典中的项没有特定顺序,以键为象征;
3. 可变长、异构、任意嵌套,同列表,嵌套可以包含列表和其他的字典等;
4. 属于可变映射类型,因为是无需,故不能进行序列操作,但可以在远处修改,通过键映射到值,字典是唯一内置的映射类型;
5. 字典存储的是对象引用,不是拷贝,和列表一样;字典的 Key 是不能变的,list 不能作为 Key,字符串、元组、整数等都可以。
关于跟踪python中列表和字典的更改?和跟踪python中列表和字典的更改命令的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于20190513——python基础(列表、数据类型:字典、列表和字典的异同)、copy()——python中列表和字典的深拷贝与浅拷贝、Python 列表和字典常踩坑即解决方案、Python 列表和字典有什么不同之处?Python 学习资料!等相关知识的信息别忘了在本站进行查找喔。
本文标签: