如何复制Python字符串?

如何复制Python字符串?,python,string,python-2.7,Python,String,Python 2.7,我这样做: 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的副本?您不需要复制Python字符串。它们是不可变的,在这种情况下,copy模

我这样做:

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
的副本?

您不需要复制Python字符串。它们是不可变的,在这种情况下,
copy
模块始终返回原始值,如
str()
、整个字符串片段,并与空字符串连接

此外,您的
'hello'
字符串被interned()。Python故意尝试只保留一个副本,因为这样可以更快地查找字典

解决此问题的一种方法是实际创建一个新字符串,然后将该字符串切回原始内容:

>>> a = 'hello'
>>> b = (a + '.')[:-1]
>>> id(a), id(b)
(4435312528, 4435312432)
但你现在所做的只是浪费记忆。毕竟,这并不是说您可以以任何方式改变这些字符串对象

如果您只想知道Python对象需要多少内存,请使用;它提供了任何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()

>>> a = 'foo'  
>>> b = '%s' % a  
>>> id(a), id(b)  
(140595444686784, 140595444726400)  

复制字符串有两种方法:复制位置a=“a”b=a,或者你可以克隆,这意味着当a被更改时,b不会受到影响,这是由a='a'b=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程序员在考虑诸如列表或DITES等深层结构时的问题:

>>> 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']可以指其他内容。

正如其他人已经解释过的,很少有实际需要,但无论如何,给你:
(适用于Python3,但Python2可能也有类似的功能)

导入ctypes
copy=ctypes.pythonapi.\u PyUnicode\u copy
copy.argtypes=[ctypes.py\u对象]
copy.restype=ctypes.py\u对象
s1='XXXXXXXXXXXX'
s2=副本(s1)
id(s1)==id(s2)#假

可以使用以下简单技巧:

a = "Python"
b = a[ : : -1 ][ : : -1 ]
print( "a =" , a )
print( "b =" , b )
a == b  # True
id( a ) == id( b ) # False

要得到与Martijin不同的答案(这是完全正确的,但不一定回答所述的问题),您可能需要提供更多的细节/用例来说明为什么要复制它。正如@elemo所暗示的,这可能是一个问题。我感兴趣的是估计
d['hello']=e
形式的嵌套字典的内存使用情况,其中
e['hi']='reach'
。为了生成这样一个嵌套字典,我生成了一个
e
字典并复制了多次。我注意到内存消耗非常低,这就引出了我的问题。现在我了解到没有创建字符串副本,因此内存消耗较低。如果希望
b
成为
a
的修改版本,而不修改
a
,只需让
b
成为任何操作的结果即可。e、 g.
b=a[2:-1]
b
设置为
'll'
,而
a
保留为
hello'
。奥利是正确的。这是因为str是不可变的类型。由于python使用了单例(可能还有其他内部优化),所以在复制e字典时,内存不会像预期的那样扩展。创建新字符串对象的方法不止一种,例如
b=''。join(a)
@martineau:当然,我真的想说“单向”。重点是“您不需要复制Python字符串“。这些操作返回相同字符串是有原因的。不过,在这种情况下,OP试图浪费内存。因为他想知道一定数量的字符串将使用多少内存,这是实际的目标。显然,他可以生成唯一的字符串,但作为一种解决方法,这是不必要的工作。+1表示“随意地”使用一个可以输出的示例。有关该行为的更多详细信息,请参阅这篇文章低估了的回答,在Python 3.6.5中不适用。id(a)和id(b)是相同的。即使我使用现代版本的format,结果也没有什么不同,即,
b='{:s}'。format(a)