-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
做两遍,错两遍,列表的可变特性 #79
Comments
1、刷题出错,即是成长线索每天在 xue.cn 上至少刷题 10 道,刷得次数多了,开始遇到之前做过的题目。很快我就发现,自己竟然在同一道题上连续错两次,这引起了我的警觉——这是重要线索,它告诉我:相关知识点,我掌握的太烂。怎么办呢?给自己充裕的时间,通过梳理的方式,彻底搞懂它。 该知识点是:python 数据容器的可变与不可变特性。题目如下:
def addItem(listParam):
listParam += [1]
mylist = [1, 2, 3, 4]
addItem(mylist)
print(len(mylist)) 2、数据容器有哪些,如何归类它们?《自学是门手艺》 书中 “数据容器” 这一节开篇即总结:
我这个人是排斥死记硬背的,可有时还必须得暂时死记硬背一下。然后赶紧通过刷题或实战巩固记忆。——但凡死记硬背之后在刷题或实战中反复出错,那就是理解没到位,得继续深究。 以上述题目而言,我清楚知道:1) 列表是可变容器 2) 变量的作用域。但我没能彻底搞懂,为什么列表可突破变量的作用域这个常规限定。 3、前人有哪些参考资料,如何使用?我搜索了一些资料,想要理解 python 数据容器是否可变的背后原理。下面这几篇给到我许多帮助:
以上有些内容,我理解起来是吃力的。我意识到,我需要按照自己的认知节奏来梳理相关知识,我还需要写一些验证代码加深影响。——仅仅阅读别人的文章或笔记,其实很难帮助自己真正掌握那个知识点,还是得自己整理归纳,梳理通顺,这个过程降低认知负担,加深知识记忆,而自己写验证代码能检查是否记住,也进一步巩固知识点记忆。 这点认识,对自学编程的人来说,大概率是老生常谈。但事情的关键不是你知道,事情的关键是自己能做到。对不对? btw,这次没能直接在官网搜一手资料。 4、可变,体现在哪些地方?通常,我们会对数据进行增删改查四大操作。但可变,并不是指代变量所存储的数据是否能发生改变。毕竟,除了区块链技术以较高的成本与性能代价能实现数据的不可删改,互联网世界的任何数据都具备删改的能力。 那么,当我们谈论 python 的数据容器是否可变时,我们到底在谈论什么?
这段文字解释的相当清楚,数据容器是否可变,并不是指代数据是否可变,而是指代数据容器的内存单元的值是否可以被改变。 那,什么是内存单元呢?
似乎可以把“内存单元的值”等同于“内存地址”。 对于新手需要知道的是, |
现在试试多引入一个变量:把变量 a 赋值给变量 b,内存地址会一样吗?如果再修改变量 b,数据和内存地址依然还一样吗? 首先,是不可变容器字符串。 从代码中可发现:把字符串 a 的值赋值给字符串 b 时,a 和 b 的数据与内存地址一样。当对字符串 b 进行修改并重新赋值给 b 时,字符串 a 的数据和内存地址保持不变,而字符串 b 的数据和内存地址发生改变。 需要注意的是, 然后,是可变容器,列表。 从代码中可发现:把列表a的值赋值给列表b时,a和b的数据与内存地址一样。当对列表b进行局部修改时,列表a和b 内存地址保持不变,和之前一样,而数据同时发生变化。 无论是字符串还是列表,我们在构建新变量 b 时,都是直接通过把变量 a 赋值给 b 即 先看看字符串。字符串没有 再看看列表。 通过切片方式构造变量 b 时,其内存地址就已经和变量 a 不同。对变量 b 进行局部数据修改时,变量 a 的数据完全不受影响。——无论是全切片,还是局部切片都如此。 通过 而这次反复难倒我的题目,涉及到函数传参。我们分别再试试看字符串和列表的表现。 先看字符串。a 作为全局变量,并没有因为被传参到函数 f 并经过处理而发生改变,数据不变,内容地址也不变。但函数内改变了字符串的数据并重新赋值给原变量时,函数体内的改参数其内存地址与数据都发生了改变。——这是符合作用域常规的现象。 再看看列表。a 作为全局变量,内存地址一直未发生变化,仅数据因为被传参到函数中发生了变化。 不难推导,如果传入函数的并不是变量 a 而是变量 a 的全切片,切片完成时已有新的内存地址指代新的变量,而变量a则不受影响。 |
What gets printed?
The text was updated successfully, but these errors were encountered: