我不知道為什么字符串和元組是不可變的;使它們不可變的優點和缺點是什么?
除了Python解釋器的內部實現,這種設計在編寫程序上是否有很好的意義?(例如,如果元組和字符串是可變的,會更容易嗎?)如果是這樣,那么選擇不可變元組和列表的例子是什么?(或pherhaps、可變字符串與python字符串)
有一種稱為函數式編程的完整編程風格,其中所有東西都是不可變的。en.wikipedia.org/wiki/functional_編程
python確實有可變的字符串和元組;它們分別拼寫為bytearray和list。
所謂的fakemutablepython Imagine a語言,你可以在搜索字符串的賦值和年齡使用列表(如mystr[0] = 'a')
a ="abc"
這是創建在內存中存儲的地址進入0x1,含"ABC",和標識符a指向它。
現在,說你做的。
b = a
本b點創建的標識符和它同一個內存地址0x1
現在,如果你的字符串是mutable,b變更:
b[0] = 'z'
這個年齡的第一個字節的字符串存儲在一個z0x1。標識符是從一個a來指向字符串,因此這會改變的,所以……
print a
print b
兩個輸出..would zbc
這可以讓一些真正奇怪,意想不到的行為。字典的鍵是一個很好的例子是這樣:
mykey = 'abc'
mydict = {
mykey: 123,
'zbc': 321
}
anotherstring = mykey
anotherstring[0] = 'z'
現在事情變得fakemutablepython奇,而你的詞典中有兩個鍵,"ABC"和"ZBC"。然后你的年齡"abc"字符串(通過"標識符"anotherstringZBC)",因此"雙鍵的安切洛蒂,ZBC"和"ZBC"……
一個可能的解決方案在本weirdness,每當你分配一個標識符的字符串(或使用它作為一個關鍵的副本),它是在具備0x1字符串。
這可防止上面的,但如果你有一個字符串,需要200內存?
a ="really, really long string [...]"
b = a
突然,你的腳本需要啟動400MB的記憶?這不是很好。
我們點什么,如果它同一個內存地址,直到我們修改它?copy on write。這個問題是相當復雜的,可以做的。
這是immutability是在哪里。而不是要求的.replace()同體復制到一個新的字符串從內存地址,然后修改它的回報。我們只是讓所有的不可變的字符串和函數,因此必須創建一個新字符串返回。這解釋了以下的代碼:
a ="abc"
b = a.replace("a","z")
證明和是由:
>>> a = 'abc'
>>> b = a
>>> id(a) == id(b)
True
>>> b = b.replace("a","z")
>>> id(a) == id(b)
False
(id()函數返回的對象的內存地址)
+1最佳答案。真的?
我聽過最好的解釋!
那么,如果我說a="abc",b="abcd"它會共享abc嗎?就像b[:4]是a?
@Dineshkumar不,我很確定"abc"和"abcd"是不同的,完全無關的,對象-stackoverflow.com/questions/5722006/…
One is performance: knowing that a
string is immutable makes it easy to
lay it out at construction time —
fixed and unchanging storage
requirements. This is also one of the
reasons for the distinction between
tuples and lists. This also allows the
implementation to safely reuse string
objects. For example, the CPython
implemenation uses pre-allocated
objects for single-character strings,
and usually returns the original
string for string operations that
doesn’t change the content.
The other is that strings in Python
are considered as"elemental" as
numbers. No amount of activity will
change the value 8 to anything else,
and in Python, no amount of activity
will change the string"eight" to
anything else.
effbot.org http:/ / / / why-are-python-strings-immutable.htm pyfaq
一大優勢是,他們制作的不可變的,他們可以被用來作為在一個字典的鍵。我可以使用內部數據結構詞典是由他們的時間點,如果把鑰匙是沒有改變。
您可以通過任何用戶創建的對象實例(顯然是可變的)進行鍵控。然后"key"可能只是內存地址,如果字符串是可變的,您仍然可以通過它們的唯一內存地址來設置key。
@triptych不是你想要的字符串——你希望它們按值鍵,否則字典就沒什么用處了……
@Hejazzman這不是python指令的工作方式。文字字符串值不用作dict鍵,而是采用字符串的哈希值。用'abc'.__hash__()向自己證明這一點。
@你說的每一句話都是錯的。首先,可以有兩個地址不同的相等字符串,因此使用該地址不起作用。第二,當dict使用字符串的散列時,關鍵是字符串本身——通過顯示d.keys()來證明它。您可以很容易地擁有兩個具有相同哈希值的字符串,而dict會將它們分開。
@標記勒索而不是地址,哈希。根據定義,不能有兩個具有相同哈希值但具有不同哈希值的字符串進行比較。
@你八年前的第一次評論是關于記憶地址的,但我當時沒有回復。正確的做法是,不能使用相同的字符串和不同的哈希值,但可以使用相同的哈希值使用不同的字符串!散列本身不足以作為密鑰,它只是機制的一部分。
@triptych我知道python dicts是如何工作的(或者任何語言的hashmaps)。這不是我的觀點。我的觀點是,相同的字符串應該能夠指向相同的條目,對于可變的字符串(以及它們作為hashmap中的鍵的"唯一內存地址")則不是這樣。然后需要有完全相同的字符串指針,而不僅僅是相同的字符串內容,才能從字典中獲取條目。
不可變的類型是conceptually多mutable比簡單酮。例如,你不constructors測量與復制或const的正確性在C + +類。越是不可變類型,語言變得更容易。因此,在最簡單的語言是純粹的功能狀態(因為沒有任何一個lambda演算的全球多更容易比圖靈機,和同樣強大的),雖然很多人不欣賞的人。
Perl的字符串函數和mutable安切洛蒂似乎只是罰款。上面的手似乎很多rationalization揮手和一個任意的設計決策。
我的答案的問題,為什么Python Python字符串不可變的安切洛蒂,Guido van Rossum通緝的創造者,因為它現在已經這樣,他都是個特殊的legions任意決策和呼吸死亡。
你可以有類似的姿勢的問題為什么Perl沒有不可變的字符串和一個完整的人會寫在passel知識觀的字符串是不可變的,以及為什么它是非常bestest IDEA"(TM)是Perl沒有他們。
Perl實際上沒有字符串:它有scalar,可以作為字符串或數字(后者有多種類型)。如果scalar是不可變的,它將成為純粹的函數Perl,世界各地的Perl開發人員將通過為自己分配UNdef來自殺。
優點:性能
缺點:你不能改變mutables。
專家:你不能改變它們