Python札记 -- 切片赋值
2013-08-16 11:37
295 查看
一、疑惑
今天在看《Python Cookbook》第四章Python技巧的4.7小节时,发现一段初看起来让人疑惑的代码。该小节的任务是将一个包含列表(行)的列表,转换成一个新的列表。新的列表包含了同样的行,但是其中一些列被删除或者重新排序了。让人疑惑的代码如下:
竹风不禁疑惑了,这第二行的代码为啥会用 "listOfRows[:] =" 这种写法?直接写成 "listOfRows =" 不行么?这两者间有什么区别呢?
二、线索
疑惑主要集中在对切片进行赋值上。抱着“实践是检验真理的唯一标准”,竹风做了个小实验:
配合注释来看的话,对切片赋值貌似是在原对象上进行修改。而且值得注意的是,切片赋值还支持元素个数不相等的操作,比如实验中用[1,2]替换了['b','c','d']。
三、真相
那么真相是什么呢,让我们继续实践一下:
直接使用 "listOfRows =" 的话,产生了一个新的对象,让我们继续看看 "listOfRows[:] =" 的效果:
最后的结束语了:列表推导会产生一个新的列表,而不是修改现有的列表。如果需要一个新的对象,那么可以使用 "listOfRows =" 写法。当需要修改一个现有的列表时,最好的办法是将现有列表的内容赋值为一个列表推导,也就是使用"listOfRows[:] =" 写法。简单地说,使用切片赋值可以修改原对象的类容,而不是创建一个新对象。谢谢大家~~
今天在看《Python Cookbook》第四章Python技巧的4.7小节时,发现一段初看起来让人疑惑的代码。该小节的任务是将一个包含列表(行)的列表,转换成一个新的列表。新的列表包含了同样的行,但是其中一些列被删除或者重新排序了。让人疑惑的代码如下:
listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]] listOfRows[:] = [[row[0], row[3], row[2]] for row in listOfRows]
竹风不禁疑惑了,这第二行的代码为啥会用 "listOfRows[:] =" 这种写法?直接写成 "listOfRows =" 不行么?这两者间有什么区别呢?
二、线索
疑惑主要集中在对切片进行赋值上。抱着“实践是检验真理的唯一标准”,竹风做了个小实验:
>>> test_li = ['a','b','c','d','e','f'] #进行测试的list >>> test_li[1:4] #简单的切片操作 ['b', 'c', 'd'] >>> id(test_li) #观察一下测试list的id 139718916544776 >>> test_li[1:4] = [1,2] #对切片进行赋值,而且是不对等的赋值 >>> test_li #观察赋值后的list ['a', 1, 2, 'e', 'f'] >>> id(test_li) #id没有变化,说明是在原对象上进行修改 139718916544776 >>>
配合注释来看的话,对切片赋值貌似是在原对象上进行修改。而且值得注意的是,切片赋值还支持元素个数不相等的操作,比如实验中用[1,2]替换了['b','c','d']。
三、真相
那么真相是什么呢,让我们继续实践一下:
>>> listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]] >>> >>> li = listOfRows >>> id(listOfRows) 139718916543336 >>> id(li) #两者的id相同,说明引用了同一个对象 139718916543336 >>> listOfRows = [[row[0], row[3], row[2]] for row in listOfRows] >>> listOfRows #使用列表推导产生的结果符合预期 [[1, 4, 3], [5, 8, 7], [9, 12, 11]] >>> li #li没有改变 [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] >>> id(listOfRows) 139718916544416 >>> id(li) #两者id不同,说明listOfRows绑定了一个新的对象 139718916543336 >>>
直接使用 "listOfRows =" 的话,产生了一个新的对象,让我们继续看看 "listOfRows[:] =" 的效果:
>>> listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]] >>> >>> li = listOfRows >>> id(listOfRows) 140034137774560 >>> id(li) #两者id一致,引用了同一个对象 140034137774560 >>> listOfRows[:] = [[row[0], row[3], row[2]] for row in listOfRows] >>> listOfRows #使用切片赋值,达到预期效果 [[1, 4, 3], [5, 8, 7], [9, 12, 11]] >>> li #li也发生了变化,因为两者绑定的是同一个对象 [[1, 4, 3], [5, 8, 7], [9, 12, 11]] >>> id(listOfRows) 140034137774560 >>> id(li) #两者的id都没有变化,说明切片赋值实在原对象上修改 140034137774560 >>>
最后的结束语了:列表推导会产生一个新的列表,而不是修改现有的列表。如果需要一个新的对象,那么可以使用 "listOfRows =" 写法。当需要修改一个现有的列表时,最好的办法是将现有列表的内容赋值为一个列表推导,也就是使用"listOfRows[:] =" 写法。简单地说,使用切片赋值可以修改原对象的类容,而不是创建一个新对象。谢谢大家~~
相关文章推荐
- Python札记 -- 切片赋值
- python切片的使用及复制列表和给列表赋值
- 通过源码分析Python中的切片赋值
- Python切片赋值
- python笔记6 - 序列,列表(生成,常用方法,运算,切片赋值),深拷贝和浅拷贝,列表推导式
- python——赋值与深浅拷贝
- 1.1Python解压序列赋值给多个变量
- Python 字典的创建赋值和动态扩展
- python变量赋值
- Python学习入门基础教程(learning Python)--6.3 Python的list切片高级
- Python列表切片详解([][:][::])
- python切片及sys.argv[]用法详解
- python如何对list进行切片操作
- 从0开始学Python:8、切片
- Python学习 Day 4 函数 切片 迭代 列表生成式 生成器
- Python学习札记(八) Basic5 循环
- Python3 Tkinter基础 Button Entry insert delete 点击按钮 向输入框赋值 或 清空输入框中的内容
- python 切片
- python基础之玩转(变量赋值)
- python之切片操作符(Slice)