Saya melakukan ini:
a = 'hello'
Dan sekarang saya hanya ingin salinan independen dari a
:
import copy
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
map( id, [ a,b,c,d,e ] )
Keluar [3]:
[4365576160, 4365576160, 4365576160, 4365576160, 4365576160]
Mengapa semuanya memiliki alamat memori yang sama dan bagaimana saya bisa mendapatkan salinannya a
?
python
string
python-2.7
biasa saya
sumber
sumber
d[ 'hello' ] = e
, di manae[ 'hi' ] = 'again'
. Untuk menghasilkan kamus bersarang seperti itu, saya membuat satue
kamus dan menyalinnya beberapa kali. Saya perhatikan bahwa konsumsi memori sangat rendah, yang menyebabkan pertanyaan saya di sini. Sekarang saya mengerti bahwa tidak ada salinan string yang dibuat, karenanya konsumsi memori rendah.b
menjadi versi modifikasia
tanpa memodifikasia
, biarkanb
saja hasil operasi apa pun. misalnyab = a[2:-1]
setb
ke'll'
dana
tetap 'hello'
.Jawaban:
Anda tidak perlu menyalin string Python. Mereka tidak dapat diubah, dan
copy
modul selalu mengembalikan aslinya dalam kasus seperti itu, seperti halnyastr()
, seluruh potongan string, dan digabungkan dengan string kosong.Selain itu, Anda
'hello'
string diinternir ( string tertentu ). Python sengaja mencoba untuk menyimpan hanya satu salinan, karena itu membuat pencarian kamus lebih cepat.Salah satu cara untuk mengatasinya adalah dengan benar-benar membuat string baru, lalu memotong string itu kembali ke konten aslinya:
>>> a = 'hello' >>> b = (a + '.')[:-1] >>> id(a), id(b) (4435312528, 4435312432)
Tapi yang Anda lakukan sekarang hanyalah membuang memori. Ini tidak seolah-olah Anda dapat mengubah objek string ini dengan cara apa pun.
Jika semua yang ingin Anda ketahui adalah berapa banyak memori yang dibutuhkan objek Python, gunakan
sys.getsizeof()
; itu memberi Anda jejak memori dari objek Python apa pun.Untuk wadah, ini tidak termasuk isinya; Anda harus mengulang ke setiap penampung untuk menghitung ukuran memori total:
>>> 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
Anda kemudian dapat memilih untuk menggunakan
id()
pelacakan untuk mengambil jejak memori yang sebenarnya atau untuk memperkirakan jejak maksimum jika objek tidak di-cache dan digunakan kembali.sumber
b = ''.join(a)
.Anda dapat menyalin string dalam python melalui pemformatan string:
>>> a = 'foo' >>> b = '%s' % a >>> id(a), id(b) (140595444686784, 140595444726400)
sumber
b = '{:s}'.format(a)
Saya baru saja memulai beberapa manipulasi string dan menemukan pertanyaan ini. Saya mungkin mencoba melakukan sesuatu seperti OP, "saya yang biasa". Jawaban sebelumnya tidak menjernihkan kebingungan saya, tetapi setelah memikirkannya sedikit, saya akhirnya "mengerti".
Selama
a
,b
,c
,d
, dane
memiliki nilai yang sama, mereka referensi ke tempat yang sama. Memori disimpan. Begitu variabel mulai memiliki nilai yang berbeda, mereka mulai memiliki referensi yang berbeda. Pengalaman belajar saya berasal dari kode ini: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
Output yang dicetak adalah:
[4538504992, 4538504992, 4538504992, 4538504992, 4538504992] hello hello hello hello hello [6113502048, 4538504992, 4538504992, 4538504992, 5570935808] goodbye hello hello hello hello something
sumber
Menyalin string dapat dilakukan dengan dua cara, yaitu menyalin lokasi a = "a" b = a atau Anda dapat mengkloning yang berarti b tidak akan terpengaruh ketika a diubah yang dilakukan oleh a = 'a' b = a [:]
sumber
Dengan kata lain "id ()" bukanlah yang Anda pedulikan. Anda ingin tahu apakah nama variabel dapat dimodifikasi tanpa merusak nama variabel sumber.
>>> a = 'hello' >>> b = a[:] >>> c = a >>> b += ' world' >>> c += ', bye' >>> a 'hello' >>> b 'hello world' >>> c 'hello, bye'
Jika Anda terbiasa dengan C, maka ini seperti variabel penunjuk kecuali Anda tidak dapat membatalkan referensi mereka untuk mengubah apa yang mereka tunjuk, tetapi id () akan memberi tahu Anda di mana mereka saat ini menunjuk.
Masalah bagi programmer python muncul ketika Anda mempertimbangkan struktur yang lebih dalam seperti list atau dicts:
>>> o={'a': 10} >>> x=o >>> y=o.copy() >>> x['a'] = 20 >>> y['a'] = 30 >>> o {'a': 20} >>> x {'a': 20} >>> y {'a': 30}
Di sini o dan x merujuk ke dikt yang sama o ['a'] dan x ['a'], dan dikt itu "bisa berubah" dalam arti bahwa Anda dapat mengubah nilai untuk kunci 'a'. Itulah mengapa "y" perlu menjadi salinan dan y ['a'] bisa merujuk ke sesuatu yang lain.
sumber