[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있습니까?



답변

Python 문자열을 복사 할 필요 가 없습니다 . 그것들은 불변이며, copy모듈은 do str(), 전체 문자열 슬라이스 및 빈 문자열로 연결하는 경우와 같은 경우 항상 원본을 반환 합니다.

또한, 귀하의 'hello'문자열은 인턴됩니다 ( 특정 문자열은 ). 파이썬은 딕셔너리 조회 속도를 높이기 때문에 의도적으로 하나의 복사본 만 유지하려고합니다.

이 문제를 해결할 수있는 한 가지 방법은 실제로 새 문자열을 만든 다음 해당 문자열을 다시 원래 내용으로 분할하는 것입니다.

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

하지만 지금하고있는 일은 기억을 낭비하는 것뿐입니다. 결국 이러한 문자열 객체를 어떤 식 으로든 변경할 수있는 것처럼 보이지는 않습니다.

알고 싶은 것이 파이썬 객체에 필요한 메모리 양뿐이라면 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()추적을 사용하여 실제 메모리 공간을 사용하거나 객체가 캐시 및 재사용되지 않은 경우 최대 공간을 추정 하도록 선택할 수 있습니다 .


답변

문자열 형식을 통해 파이썬에서 문자열을 복사 할 수 있습니다.

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


답변

방금 문자열 조작을 시작 하고이 질문을 찾았습니다. 나는 아마도 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


답변

문자열 복사는 두 가지 방법으로 수행 할 수 있습니다. a = “a”b = a 위치를 복사하거나 a = ‘a’b = a [:]에 의해 수행되는 a가 변경 될 때 b가 영향을받지 않음을 의미하는 복제 할 수 있습니다.


답변

다르게 말하면 “id ()”는 당신이 신경 쓰는 것이 아닙니다. 소스 변수 이름을 손상시키지 않고 변수 이름을 수정할 수 있는지 알고 싶습니다.

>>> a = 'hello'
>>> b = a[:]
>>> c = a
>>> b += ' world'
>>> c += ', bye'
>>> a
'hello'
>>> b
'hello world'
>>> c
'hello, bye'

C에 익숙하다면 포인터 변수와 비슷하지만 가리키는 내용을 수정하기 위해 역 참조 할 수는 없지만 id ()는 현재 가리키는 위치를 알려줍니다.

파이썬 프로그래머의 문제는 목록이나 사전과 같은 더 깊은 구조를 고려할 때 발생합니다.

>>> 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’]는 다른 것을 참조 할 수 있습니다.


답변