我这样做:
a = 'hello'
现在我只想要一个独立的副本a
:
import copy
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
map( id, [ a,b,c,d,e ] )
出[3]:
[4365576160, 4365576160, 4365576160, 4365576160, 4365576160]
为什么它们都具有相同的内存地址,我如何获得副本a
?
我这样做:
a = 'hello'
现在我只想要一个独立的副本a
:
import copy
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
map( id, [ a,b,c,d,e ] )
出[3]:
[4365576160, 4365576160, 4365576160, 4365576160, 4365576160]
为什么它们都具有相同的内存地址,我如何获得副本a
?
d[ 'hello' ] = e
where的字典的内存使用情况很感兴趣e[ 'hi' ] = 'again'
。为了生成这样的嵌套字典,我生成了一个e
字典并多次复制了它。我注意到内存消耗非常低,这引起了我的疑问。现在我知道没有创建字符串副本,因此内存消耗低。
b
成为a
不修改的修改版本a
,只需让它b
成为任何操作的结果即可。例如,b = a[2:-1]
套b
到'll'
和a
遗体“ hello'
。
Answers:
您无需复制Python字符串。它们是不可变的,copy
在这种情况下,模块始终返回原始值,例如do str()
,整个字符串切片,并与空字符串连接。
此外,您的'hello'
字符串已被扣留(某些字符串是)。Python故意尝试仅保留一个副本,因为这会使字典查找更快。
解决此问题的一种方法是实际创建一个新字符串,然后将该字符串切回到原始内容:
>>> a = 'hello'
>>> b = (a + '.')[:-1]
>>> id(a), id(b)
(4435312528, 4435312432)
但是您现在要做的只是浪费内存。毕竟,似乎您无法以任何方式使这些字符串对象发生变异。
如果您只想知道Python对象需要多少内存,请使用sys.getsizeof()
; 它为您提供了任何Python对象的内存占用量。
对于集装箱这并没有包括的内容; 您必须递归到每个容器中以计算总内存大小:
>>> import sys
>>> a = 'hello'
>>> sys.getsizeof(a)
42
>>> b = {'foo': 'bar'}
>>> sys.getsizeof(b)
280
>>> sys.getsizeof(b) + sum(sys.getsizeof(k) + sys.getsizeof(v) for k, v in b.items())
360
然后,id()
如果未缓存和重用对象,则可以选择使用跟踪来获取实际的内存占用空间或估计最大占用空间。
b = ''.join(a)
。
您可以通过字符串格式在python中复制字符串:
>>> a = 'foo'
>>> b = '%s' % a
>>> id(a), id(b)
(140595444686784, 140595444726400)
b = '{:s}'.format(a)
我刚刚开始一些字符串操作,发现了这个问题。我可能正在尝试执行OP,“通常是我”。先前的答案并没有消除我的困惑,但是经过一番思考之后,我终于“明白了”。
只要a
,b
,c
,d
,并且e
具有相同的价值,他们引用了同一个地方。内存已保存。一旦变量开始具有不同的值,它们就会开始具有不同的引用。我的学习经验来自以下代码:
import copy
a = 'hello'
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
print map( id, [ a,b,c,d,e ] )
print a, b, c, d, e
e = a + 'something'
a = 'goodbye'
print map( id, [ a,b,c,d,e ] )
print a, b, c, d, e
打印输出为:
[4538504992, 4538504992, 4538504992, 4538504992, 4538504992]
hello hello hello hello hello
[6113502048, 4538504992, 4538504992, 4538504992, 5570935808]
goodbye hello hello hello hello something
换句话说,“ id()”并不是您所关心的。您想知道是否可以在不损害源变量名称的情况下修改变量名称。
>>> a = 'hello'
>>> b = a[:]
>>> c = a
>>> b += ' world'
>>> c += ', bye'
>>> a
'hello'
>>> b
'hello world'
>>> c
'hello, bye'
如果您习惯使用C,那么它们就像指针变量,只是您不能取消引用它们以修改它们指向的内容,但是id()会告诉您它们当前指向的位置。
当您考虑更深层次的结构(例如列表或字典)时,Python程序员就会遇到问题:
>>> o={'a': 10}
>>> x=o
>>> y=o.copy()
>>> x['a'] = 20
>>> y['a'] = 30
>>> o
{'a': 20}
>>> x
{'a': 20}
>>> y
{'a': 30}
在这里,o和x指的是相同的dict o ['a']和x ['a'],并且该dict是“可变的”,因为您可以更改键“ a”的值。这就是为什么“ y”需要为副本,而y ['a']可以引用其他内容的原因。