一、疑惑
    今天在看《Python Cookbook》第四章Python技巧的4.7小节时,发现一段初看起来让人疑惑的代码。该小节的任务是将一个包含列表(行)的列表,转换成一个新的列表。新的列表包含了同样的行,但是其中一些列被删除或者重新排序了。让人疑惑的代码如下:

1 listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
2 listOfRows[:] = [[row[0], row[3], row[2]] for row in listOfRows]

竹风不禁疑惑了,这第二行的代码为啥会用 "listOfRows[:] =" 这种写法?直接写成 "listOfRows =" 不行么?这两者间有什么区别呢?

二、线索
    疑惑主要集中在对切片进行赋值上。抱着“实践是检验真理的唯一标准”,竹风做了个小实验:

 1 >>> test_li = ['a','b','c','d','e','f']    #进行测试的list
 2 >>> test_li[1:4]    #简单的切片操作
 3 ['b', 'c', 'd']
 4 >>> id(test_li)    #观察一下测试list的id
 5 139718916544776
 6 >>> test_li[1:4] = [1,2]    #对切片进行赋值,而且是不对等的赋值
 7 >>> test_li    #观察赋值后的list
 8 ['a', 1, 2, 'e', 'f']
 9 >>> id(test_li)    #id没有变化,说明是在原对象上进行修改
10 139718916544776
11 >>>

配合注释来看的话,对切片赋值貌似是在原对象上进行修改。而且值得注意的是,切片赋值还支持元素个数不相等的操作,比如实验中用[1,2]替换了['b','c','d']。

三、真相
    那么真相是什么呢,让我们继续实践一下:

 1 >>> listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
 2 >>>
 3 >>> li = listOfRows
 4 >>> id(listOfRows)
 5 139718916543336
 6 >>> id(li)    #两者的id相同,说明引用了同一个对象
 7 139718916543336
 8 >>> listOfRows = [[row[0], row[3], row[2]] for row in listOfRows]
 9 >>> listOfRows    #使用列表推导产生的结果符合预期
10 [[1, 4, 3], [5, 8, 7], [9, 12, 11]]
11 >>> li    #li没有改变
12 [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
13 >>> id(listOfRows)
14 139718916544416
15 >>> id(li)    #两者id不同,说明listOfRows绑定了一个新的对象
16 139718916543336
17 >>>

直接使用 "listOfRows =" 的话,产生了一个新的对象,让我们继续看看 "listOfRows[:] =" 的效果:

 1 >>> listOfRows = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
 2 >>>
 3 >>> li = listOfRows
 4 >>> id(listOfRows)
 5 140034137774560
 6 >>> id(li)    #两者id一致,引用了同一个对象
 7 140034137774560
 8 >>> listOfRows[:] = [[row[0], row[3], row[2]] for row in listOfRows]
 9 >>> listOfRows    #使用切片赋值,达到预期效果
10 [[1, 4, 3], [5, 8, 7], [9, 12, 11]]
11 >>> li    #li也发生了变化,因为两者绑定的是同一个对象
12 [[1, 4, 3], [5, 8, 7], [9, 12, 11]]
13 >>> id(listOfRows)
14 140034137774560
15 >>> id(li)    #两者的id都没有变化,说明切片赋值实在原对象上修改
16 140034137774560
17 >>>

最后的结束语了:列表推导会产生一个新的列表,而不是修改现有的列表。如果需要一个新的对象,那么可以使用 "listOfRows ="  写法。当需要修改一个现有的列表时,最好的办法是将现有列表的内容赋值为一个列表推导,也就是使用"listOfRows[:] =" 写法。简单地说,使用切片赋值可以修改原对象的类容,而不是创建一个新对象。谢谢大家~~

转载于:https://www.cnblogs.com/PandaBamboo/p/3261646.html

Python札记 -- 切片赋值相关推荐

  1. python列表切片赋值_Python中对切片赋值原理分析

    有这么个问题::t = [1, 2, 3] t[1:1] = [7] print t  # 输出 [1, 7, 2, 3] 谁会对列表这么进行赋值呢?但是对于这个输出结果的原因确实值得去再了解下,今天 ...

  2. python数组切片赋值_基于numpy中数组元素的切片复制方法

    代码1: #!/usr/bin/python import numpy as np arr1 = np.arange(10) print(arr1) slice_data = arr1[3:5] pr ...

  3. python列表切片得到的是列表还是字符串_python中列表的切片问题 python arry怎么取列切片...

    python 列表切片赋值 对列表切片进行赋值,解释器处理时是直接将序列中的内容赋值过去的 ,还切片赋值,得到的与原变量无关,是两个不同的对象:直接赋值,引用的是同一个对象. 请看下例 切片赋值. a ...

  4. python列表赋值 连续整数_列表切片赋值,小技巧(Python基础)。

    列表的操作相对我还是比较熟悉的,累的时候看一些基础教程,巩固加补充知识点. 随便提示一下,list命令不是函数,是一个类. 列表的切片赋值: In [1]: name = list('sidian') ...

  5. 关于学习Python的一点学习总结(5->切片赋值->sort排序->列表操作)

    16.给切片赋值: >>> test=list('hello')>>> test['h', 'e', 'l', 'l', 'o']>>> test ...

  6. python中的赋值和深浅拷贝

    赋值 在python中,赋值仅仅是复制了对象的引用,并没有开辟内存空间 a = 1 b = a 上述代码只是把a的引用复制给了b,结果是a和b同时指向1 对于可变对象 a = [1, 2, 3] b ...

  7. python数组切片教程_手把手numpy教程【二】——数组与切片

    今天是Numpy专题的第二篇,我们来进入正题,来看看Numpy的运算. 上一篇文章当中曾经提到过,同样大小的数据,使用Numpy的运算速度会是我们自己写循环来计算的上百倍甚至更多.并且Numpy的AP ...

  8. python 赋值方法_基于Python List的赋值方法

    Python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不 ...

  9. python步骤切片_python中的切片操作

    之前在做毕业设计的时候随手写过python中":"的作用,即python的切片操作. 记得刚开始学切片这一节的时候,看完之后,做了作业,感觉记忆深刻.学到后面很多地方都可以用到切片 ...

最新文章

  1. linux如何生成javacore文件,如何产生javacore和heapdump文件》
  2. mysql 存储过程执行慢_MySQL存储过程因为字符集不同导致执行慢
  3. 基于ArcGIS JS API 的点击查询功能
  4. 基于pygame的贪吃蛇游戏
  5. C error :Run-Time Check Failure #2 - Stack around the variable 'b' was corrupted.
  6. 许海燕(1987-),女,宁波市智慧城市规划标准发展研究院研究人员.
  7. java 标题栏_如何更改java应用程序标题栏默认图标
  8. 微信小游戏飞机大战Cocos Creator+TypeScript
  9. 三极管什么时候工作在饱和区
  10. 蚂蚁迷宫—有限状态机设计(ANT MAZE)
  11. KMPlayer怎么加速播放 KMPlayer加速播放方法
  12. vue 动态 Prop
  13. 内网渗透-PTHPTTPTK
  14. Windows系统下的NTP时间同步
  15. SQL SERVER 2008 R2的累计补丁下载地址
  16. [NOI2016] 优秀的拆分 题解
  17. 微信小程序使用高德SDK获取天气
  18. Liferay7开发系列(一)介绍 liferay版本:7.1.2
  19. neovim符号自动补全auto-pairs
  20. 不会聊天,怎么可能找到女朋友?

热门文章

  1. C#入门4——税收计算
  2. 第十四章 使用者的特殊 shell 与 PAM 模块
  3. React+ant中的Form表单的刷新
  4. 微信小程序: 开发文档
  5. 手机图片怎么做成笔记 手机照片笔记怎么制作
  6. 百年工业,名词满天飞
  7. Javascript 报错 Uncaught TypeError: x is not a function 常见错误总结
  8. dev C++遇到endl无法调试的解决方法
  9. 没有学历怎么找运维工作?
  10. VINS-Mono翻译