浅拷贝,为什么列表没有改变(Shallow copy, why does the list not change)
我想了解python中浅拷贝和深拷贝之间的区别。 我在这里阅读了很多帖子,他们一直很有帮助。 但是,我仍然不太了解这种差异。 有人可以请解释下面结果的原因。 评论中指出了我不理解的结果。
非常感谢。
import copy import random class understand_copy(object): def __init__(self): self.listofvalues = [4, 5] def set_listofvalues(self, pos, value): self.listofvalues[pos] = value ins = understand_copy() newins = copy.copy(ins) newins.set_listofvalues(1,3) print "ins = ", ins.listofvalues print "in newins", newins.listofvalues # Gives the following output as I would expect based on the explanations. # prints ins = [4, 3] # prints newins = [4, 3] newins.listofvalues.append(5) print "ins =", ins.listofvalues print "newins =", newins.listofvalues # Gives the following output as I would expect based on the explanations. # prints ins = [4, 3, 5] # prints newins = [4, 3, 5] newins.listofvalues = [10, 11] print "ins = ", ins.listofvalues print "newins = ", newins.listofvalues # Gives # ins = [4, 3, 5] # newins = [10, 11] # This is the output that I do not understand. # Why does ins.listofvalues not change this case.**
I am trying to understand the difference between shallow copy and deep copy in python. I read many posts here and they have been helpful. However, I still don't understand the difference well. Can someone please explain the reason for the result below. The result that I do not understand is indicated in the comments.
Thanks very much.
import copy import random class understand_copy(object): def __init__(self): self.listofvalues = [4, 5] def set_listofvalues(self, pos, value): self.listofvalues[pos] = value ins = understand_copy() newins = copy.copy(ins) newins.set_listofvalues(1,3) print "ins = ", ins.listofvalues print "in newins", newins.listofvalues # Gives the following output as I would expect based on the explanations. # prints ins = [4, 3] # prints newins = [4, 3] newins.listofvalues.append(5) print "ins =", ins.listofvalues print "newins =", newins.listofvalues # Gives the following output as I would expect based on the explanations. # prints ins = [4, 3, 5] # prints newins = [4, 3, 5] newins.listofvalues = [10, 11] print "ins = ", ins.listofvalues print "newins = ", newins.listofvalues # Gives # ins = [4, 3, 5] # newins = [10, 11] # This is the output that I do not understand. # Why does ins.listofvalues not change this case.**
原文:https://stackoverflow.com/questions/4530978
最满意答案
这个:
let product'' = dbresult { let! custId = getCustomerId "Alice" let! orderId = getLastOrderForCustomer "" // error! let! productId = getLastProductForOrder orderId printfn "Product is %s" productId return productId }
desugar to like like(将monad类型命名为
DB<'t>
):let product'' = DB.Delay(fun () -> DB.Bind(getCustomerId "Alice",(fun custId -> DB.Bind(getLastOrderForCustomer "",(fun orderId -> DB.Bind(getLastProductForOrder orderId, (fun productId -> printfn "Product is %s" productId DB.Return productId)))))))
所以基本上你可以得到每个
let!
的Bind
级别let!
(你通常可以忽略Delay
)正如您所看到的, 计算表达式语法比嵌套
Binds
更好 - 大多数支持某种类型的monadic表达式的语言具有类似的语法糖 - 甚至C#(from ... in ... select
aka LINQ)this:
let product'' = dbresult { let! custId = getCustomerId "Alice" let! orderId = getLastOrderForCustomer "" // error! let! productId = getLastProductForOrder orderId printfn "Product is %s" productId return productId }
will desugar to something like (naming the monad type as just
DB<'t>
):let product'' = DB.Delay(fun () -> DB.Bind(getCustomerId "Alice",(fun custId -> DB.Bind(getLastOrderForCustomer "",(fun orderId -> DB.Bind(getLastProductForOrder orderId, (fun productId -> printfn "Product is %s" productId DB.Return productId)))))))
so basically you get a
Bind
level for eachlet!
(you can usually ignore theDelay
)As you can see the computational expression syntax is much nicer than the nested
Binds
- most languages which supports monadic expressions of some sort have similar syntactic sugar - even C# (from ... in ... select
aka LINQ)
相关问答
更多-
在以下情况下将数据写入文件: 调用session_write_close() 脚本执行完成 因此,如果你不做1),你的第二个假设是正确的。 每次变量更改时写入文件都非常昂贵,因为一般来说访问和写入磁盘很慢,因此PHP不会这样做。 但应该注意的是,诸如memcache或redis之类的缓存系统会在发生变化时存储变化,因此当PHP会话在可靠性方面不够时,依赖它们是一个好主意。 Data is written to file if: session_write_close() is called the scri ...
-
delete仅适用于可删除的属性。 函数声明如下: function f(){ } 不可删除。 尝试对原始函数声明使用此语法: foo = function (){var bar=0; return function(){return bar++;}} 在这里看到: http : //jsfiddle.net/Sxnaw/ 您可以阅读本文以深入解释可删除和不可删除的属性: http : //perfectionkills.com/understanding-delete/ delete only wor ...
-
想象一下,查询被远程转移到数据库。 数据库引擎应该如何通过互联网访问, 因为它正在执行查询并告诉计算机上的“count”变量自行更新? 这样做没有标准的机制,因此任何会改变本地机器上的变量的东西都不能放入将在远程机器上运行的表达式树中。 更一般地说, 在执行时导致副作用的查询是非常非常糟糕的查询 。 永远不会在查询中产生副作用,即使在这样做是合法的情况下也是如此。 这可能非常令人困惑。 请记住, 查询不是for循环 。 查询结果是对象表示查询 ,而不是查询 结果 。 执行时具有副作用的查询将在要求其结果两次 ...
-
根据您链接的github文档以及开发人员界面 ,您必须将run_pending()和某种长度的sleep放在无限循环中。 您不需要从另一个线程运行调度程序,除非您在主线程中进行除调度之外的任何操作。 如果你只是用它来安排,那就没有必要。 如果关闭终端,整个程序关闭,所以是终端需要保持打开状态。 Based on the github doc you had linked, as well as the developer interface, you do have to put run_pending() ...
-
请耐心等待,准确无误。 FUNCTION MoveTower(disk, source, dest, spare): 1. IF disk == 0, THEN: 2. move disk from source to dest 3. ELSE: 4. MoveTower(disk - 1, source, spare, dest) 5. move disk from source to dest 6. MoveTow ...
-
异步线程的机制(Mechanics of Asynchronous Threads)[2023-11-07]
我相信这篇MSDN文章应该回答你的所有问题。 请注意,您的大部分直觉实际上都是正确的。 您需要做的就是研究细节。 在.NET Framework中编写线程池 I believe this MSDN article should answer all your questions. Take note that most of your intuition is in fact correct. All you need to do is research the details. Programming t ... -
事实上,如果你仔细想想,这个解释起来很容易。 所以,让我们从基础开始。 边界是如何呈现的? 首先,我们来看一个正常的边框(边框:10px纯黑色;背景:绿色): 看起来就像你所期望的一样。 现在,让我们用各种不同的颜色来看它: 正如你所看到的,边界被均匀地绘制,并以一定的角度被加入。 在你的例子中有一个border: 40px solid green; 。 这意味着整个边框宽40px,绿色。 强调一下,这里有一个夸张边界的形状。 宽度和高度都是0,所以这是所有边界: 在这一点上,如果我们使左边框透明,它将只是 ...
-
Go:二进制编码的机制(Go: Mechanics of binary encoding)[2023-07-11]
编码/二进制/ varint.go package binary // This file implements "varint" encoding of 64-bit integers. // The encoding is: // - unsigned integers are serialized 7 bits at a time, starting with the // least significant bits // - the most significant bit (msb) in ... -
为什么调用DerivedClass.foo()? 目标还没有准备好,所以对它做任何事情都是我眼中的废话。 不。该对象已经创建。 构造函数不创建对象,只是初始化它们。 该对象由new操作员在此创建。 我会期待SuperClass.foo()被调用 正如已经解释的那样,并不是没有创建对象。 它已经是。 该调用将调用重写的方法。 这就是为什么你不应该从构造函数调用重写方法的原因。 你会看到意想不到的行为。 SuperClass不知道任何派生类。 那么,它不需要知道。 方法调用调用派生类方法的事实与超类是否知道子类 ...
-
这个: let product'' = dbresult { let! custId = getCustomerId "Alice" let! orderId = getLastOrderForCustomer "" // error! let! productId = getLastProductForOrder orderId printfn "Product is %s" productId return pr ...