2014-07-17 75 views
42

我這樣做:如何複製Python字符串?

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

+2

若要回答Martijin的(這是完全正確的,雖然不一定回答問題的陳述),你可能不同想要提供更多的細節/用例來顯示**爲什麼**你想拷貝它。 – elmo

+4

正如@elemo所暗示的,這可能是[XY問題](http://www.perlmonks.org/?node=XY+Problem)。 – martineau

+2

我有興趣估計形式爲'd ['hello'] = e'的嵌套字典的內存使用情況,其中'e ['hi'] ='again''。爲了生成這樣的嵌套字典,我生成了一個單獨的「e」字典並且多次拷貝它。我注意到內存消耗非常低,這引起了我的問題。現在我明白了,沒有創建字符串副本,因此內存消耗低。 –

回答

92

你不需要需要複製一個Python字符串。它們是不可變的,copy模塊總是在這種情況下返回原始數據,就像str()(整個字符串切片)以及與空字符串連接一樣。

此外,您的'hello'字符串是internedcertain strings are)。 Python故意試圖保留一個副本,因爲這樣可以更快地查找字典。你能解決這個

一種方法是實際創建一個新的字符串,然後切片該字符串回原來的內容:

>>> a = 'hello' 
>>> b = (a + '.')[:-1] 
>>> id(a), id(b) 
(4435312528, 4435312432) 

但所有你現在正在做的是浪費內存。畢竟,你不能以任何方式改變這些字符串對象。

如果您只想知道Python對象需要多少內存,請使用sys.getsizeinfo();它爲您提供了任何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()跟蹤進行實際的內存佔用或估計最大的足跡,如果對象將不緩存和重用。

+3

創建新字符串對象的方法不止一種,如'b =''.join(a)'。 – martineau

+0

@馬蒂諾:當然,我真的想說'單向'。 –

+10

強調「你不需要複製Python字符串」。這些操作簡單地返回相同的字符串是有原因的。 – tcooc

3

您可以在python通過字符串格式複製的字符串:

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

複製字符串可以通過兩種方式可以複製的位置=「」 B = A,也可以克隆這件裝置B不會當a被更改時會受到影響a ='a'b = a [:]

2

我剛開始一些字符串操作並發現了這個問題。我可能正在嘗試做類似於OP的事情,「通常我」。以前的答案並沒有解決我的困惑,但在想了一下之後,我終於「明白了」。

只要abcd,和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 
+0

有關行爲的更多詳細信息在本文中描述https://stackoverflow.com/questions/2123925/when-does-python-allocate-new-memory-for-identical-strings – dlasalle

相關問題