- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在一个章节中,作者写了两句自相矛盾的句子。
第一个:
A shallow copy of an object is defined to be a newly created object of the same
type as the original object whose contents are references to the elements in the
original object.
第二个:
when shallow copies are made, the string is explicitly copied and a new (string)
object created
第一句表示浅复制时字符串对象和列表对象都是引用(未显式复制)。
第二句表示浅复制时显式复制字符串对象。
我认为第一句话是对的。我认为第二个应该是:
when "wifey[0] = 'jane'" is executed, the string is explicitly copied and a new
(string) object created
我不知道作者为什么要写第二个。我说得对吗?
这是全部 Material :
6.20。 *复制Python对象以及浅拷贝和深拷贝
前面在 3.5 节中,我们描述了对象赋值如何简单地成为对象引用。这意味着当您创建一个对象,然后将该对象分配给另一个变量时,Python 不会复制该对象。相反,它仅复制对该对象的引用。
例如,假设您想为一对年轻夫妇创建一个通用配置文件;称之为人。然后为他们两个复制这个对象。在下面的示例中,我们展示了两种复制对象的方法,一种使用切片,另一种使用工厂函数。为了显示我们有三个不相关的对象,我们使用 id() 内置函数来显示每个对象的标识。 (我们也可以使用 is 运算符来做同样的事情。)
>>> person = ['name', ['savings', 100.00]]
>>> hubby = person[:] # slice copy
>>> wifey = list(person) # fac func copy
>>> [id(x) for x in person, hubby, wifey]
[11826320, 12223552, 11850936]
为他们创建个人储蓄账户,初始存款为 100 美元。更改名称以定制每个人的对象。但当丈夫提取 50 美元时,他的行为影响了妻子的账户,尽管单独制作了副本。 (当然,这是假设我们希望他们拥有单独的帐户,而不是单一的联合帐户。)这是为什么?
>>> hubby[0] = 'joe'
>>> wifey[0] = 'jane'
>>> hubby, wifey
(['joe', ['savings', 100.0]], ['jane', ['savings', 100.0]])
>>> hubby[1][1] = 50.00
>>> hubby, wifey
(['joe', ['savings', 50.0]], ['jane', ['savings', 50.0]])
原因是我们只做了浅拷贝。 对象的浅拷贝被定义为与原始对象类型相同的新创建的对象,其内容是对原始对象中元素的引用。换句话说,复制的对象本身是新,但内容不新。序列对象的浅拷贝是默认的拷贝类型,可以通过多种方式进行:(1) 获取完整的切片 [:],(2) 使用工厂函数,例如 list()、dict()、等等,或者(3)使用copy模块的copy()函数。
您的下一个问题应该是:当妻子的名字被分配时,为什么它没有影响丈夫的名字?他们现在不应该都叫“简”吗?它起作用并且我们没有重复名称的原因是因为每个列表中都有两个对象,第一个是不可变的(字符串),第二个是可变的(列表)。因此,当进行浅拷贝时,会显式复制字符串并创建一个新的(字符串)对象,而列表仅复制其引用,而不复制其成员。因此,更改姓名不是问题,但更改银行信息的任何部分才是问题。在这里,让我们看一下每个列表元素的对象 ID。请注意,银行对象完全相同,并且其中一个对象的更改会影响另一个对象。请注意,在我们更改名称后,新的名称字符串如何替换原始的“名称”字符串:
之前:
>>> [id(x) for x in hubby]
[9919616, 11826320]
>>> [id(x) for x in wifey]
[9919616, 11826320]
之后:
>>> [id(x) for x in hubby]
[12092832, 11826320]
>>> [id(x) for x in wifey]
[12191712, 11826320]
最佳答案
Your next question should be: When the wife's name is assigned, how come it did not affect the husband's name? Shouldn't they both have the name 'jane' now? The reason why it worked and we don't have duplicate names is because of the two objects in each of their lists, the first is immutable (a string) and the second is mutable (a list).
虽然引用的事实是真实的,但这种解释是不正确的。事实上,它之所以有效并且我们没有重复的名称的原因是 wifey[0] = 'jane'
行为 wifey
的元素分配了一个新值>,这是与 hubby
不同的列表。相比之下,hubby[1][1] = 50.0
行没有为 hubby
的元素分配新值。相反,它为 hubby[1]
的元素分配了一个新值,正如前面所讨论的,它与 wifey[1]
是同一对象。
hubby[0]
和 wifey[0]
恰好是不可变值这一事实是正确的,但无关紧要。
您可以按如下方式证明这一点:
person = [[], ['savings', 100.00]]
hubby = list(person)
wifey = list(person)
因此,这两个元素都是可变的,因为它们都是列表。
hubby[0] = [1,2,3]
id(hubby[0])
id(wifey[0])
看哪,现在第一个元素引用了不同的列表!
Because of this, when shallow copies are made, the string is explicitly copied and a new (string) object created while the list only has its reference copied, not its members.
我想不出任何方法可以将其解释为正确。如果您对包含字符串的内容进行浅拷贝,则不会复制该字符串。列表的情况完全相同,如果您对包含列表的内容进行浅拷贝,则不会复制该列表。
如果您复制字符串本身,则实际上不需要复制字符串still(因为它是不可变的)。作为一种优化,您可以再次返回相同的对象,并且对于大多数目的来说,这同样好。事实上,Python 2.7.5 和 Python 3.2.5(这是我在这里安装的)都对 original[:]
、str(original)
的所有三个进行了优化> 和 copy.copy(original)
。
如果出于某种晦涩的原因,您实际上想要两个不相同的相等字符串(也许是为了测试 ==
的性能或其他东西,我不知道),那么您基本上必须尝试欺骗 Python 运行时:(original + ' ')[0:-1]
或其他。
关于python - 这是核心Python编程第二版的错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19630023/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!