이 답변 은 파이썬 랜드에서 왜 이런 일이 발생 하는지 실제로 설명하기 위해 사용할 코드를 제공하지 않습니다 . 그리고 이것은 더 깊은 접근법으로 보는 것이 재미있어서 여기로갑니다.
이것이 예상대로 작동하지 않는 주된 이유는 파이썬에서 작성할 때 다음과 같습니다.
i += 1
그것은 당신이 생각하는 것을하지 않습니다. 정수는 불변입니다. 파이썬에서 객체가 실제로 무엇인지 살펴볼 때 볼 수 있습니다.
a = 0
print('ID of the first integer:', id(a))
a += 1
print('ID of the first integer +=1:', id(a))
id 함수 는 수명 동안 객체의 고유하고 일정한 값을 나타냅니다. 개념적으로 C / C ++의 메모리 주소에 느슨하게 매핑됩니다. 위의 코드를 실행 :
ID of the first integer: 140444342529056
ID of the first integer +=1: 140444342529088
즉, id가 다르기 때문에 first a
는 더 이상 second와 동일하지 않습니다 a
. 효과적으로 그들은 메모리의 다른 위치에 있습니다.
그러나 객체를 사용하면 상황이 다르게 작동합니다. +=
여기 에 연산자를 덮어 썼습니다 .
class CustomInt:
def __iadd__(self, other):
# Override += 1 for this class
self.value = self.value + other.value
return self
def __init__(self, v):
self.value = v
ints = []
for i in range(5):
int = CustomInt(i)
print('ID={}, value={}'.format(id(int), i))
ints.append(int)
for i in ints:
i += CustomInt(i.value)
print("######")
for i in ints:
print('ID={}, value={}'.format(id(i), i.value))
이를 실행하면 다음과 같은 결과가 나타납니다.
ID=140444284275400, value=0
ID=140444284275120, value=1
ID=140444284275064, value=2
ID=140444284310752, value=3
ID=140444284310864, value=4
######
ID=140444284275400, value=0
ID=140444284275120, value=2
ID=140444284275064, value=4
ID=140444284310752, value=6
ID=140444284310864, value=8
이 경우 id 속성이 실제로 것을 알 같은 당신은 또한 찾을 수 (개체의 값이 다른 경우에도 모두 반복에 대한 id
이 돌연변이대로 변경 될 오브젝트가 보유하고있는 INT 값의를 - 정수 때문에 불변입니다).
불변 객체로 동일한 운동을 실행할 때와 이것을 비교하십시오.
ints_primitives = []
for i in range(5):
int = i
ints_primitives.append(int)
print('ID={}, value={}'.format(id(int), i))
print("######")
for i in ints_primitives:
i += 1
print('ID={}, value={}'.format(id(int), i))
print("######")
for i in ints_primitives:
print('ID={}, value={}'.format(id(i), i))
이 결과는 다음과 같습니다.
ID=140023258889248, value=0
ID=140023258889280, value=1
ID=140023258889312, value=2
ID=140023258889344, value=3
ID=140023258889376, value=4
######
ID=140023258889280, value=1
ID=140023258889312, value=2
ID=140023258889344, value=3
ID=140023258889376, value=4
ID=140023258889408, value=5
######
ID=140023258889248, value=0
ID=140023258889280, value=1
ID=140023258889312, value=2
ID=140023258889344, value=3
ID=140023258889376, value=4
여기 몇 가지주의 할 사항이 있습니다. 먼저와 루프에서 +=
더 이상 원래 객체에 추가하지 않습니다. 이 경우 int가 Python의 불변 유형 중 하나이므로 python은 다른 ID를 사용합니다. 또한 파이썬은 id
불변 값이 동일한 여러 변수에 동일한 기본 을 사용한다는 점에 주목하십시오 .
a = 1999
b = 1999
c = 1999
print('id a:', id(a))
print('id b:', id(b))
print('id c:', id(c))
id a: 139846953372048
id b: 139846953372048
id c: 139846953372048
tl; dr- 파이썬에는 소수의 불변 유형이있어서 동작이 발생합니다. 모든 변경 가능한 유형에 대한 기대치가 정확합니다.
i
변경 불가능하거나 변경하지 않는 작업을 수행하는 경우에만 해당됩니다 . 중첩 된 목록을 사용하면for i in a: a.append(1)
동작이 달라집니다. 파이썬 은 중첩리스트를 복사 하지 않습니다 . 그러나 정수는 변경할 수 없으며 더하기는 새 객체를 반환하지만 이전 객체는 변경하지 않습니다.