'for' 루프에서 i = i + 1과 i + = 1의 차이는 무엇입니까?
저는 오늘 흥미로운 사실을 발견했고, 누군가가 여기서 차이점이 무엇인지 밝혀줄 수 있는지 궁금했습니다.
import numpy as np
A = np.arange(12).reshape(4,3)
for a in A:
a = a + 1
B = np.arange(12).reshape(4,3)
for b in B:
b += 1
각각실후를 한 후for
고리,A
변경되지 않았습니다.B
각 요소에 하나씩 추가되었습니다.저는 실제로 사용합니다.B
NumPy 열버 내에서 에 쓸 for
루우프
자체를것입니다.b += 1
다른 하나는 변수를 재할당합니다.a = a + 1
.
완전성을 위해:
x += y
항상 인플레이스 작업을 수행하는 것은 아닙니다. 최소한 세 가지 예외가 있습니다.
한다면
x
를 구현하지 않습니다.__iadd__
그 다음에 방법.x += y
진술은 단지 의 약어일 뿐입니다.x = x + y
이 경우는 다음과 같습니다.x
그것은 마치 … 같았습니다.int
.한다면
__iadd__
아온다를 합니다.NotImplemented
으로 돌아갑니다.x = x + y
.그
__iadd__
방법은 이론적으로 제 자리에서 작동하지 않도록 구현될 수 있습니다.하지만 그렇게 하는 것은 정말 이상할 것입니다.
공교롭게도 당신의b
어셰numpy.ndarray
를 하는 s__iadd__
두 번째 루프가 원래 배열을 수정할 수 있도록 자체를 반환합니다.
이에 대한 자세한 내용은 "Emulating Numeric Types"의 Python 문서를 참조하십시오.
것들이▁[들]
__i*__
를 호출합니다 ] 메 호 증 산 할 구 합 현 니 다 을 당 술 서 드 를 출+=
,-=
,*=
,@=
,/=
,//=
,%=
,**=
,<<=
,>>=
,&=
,^=
,|=
). 을 제자리에서될 수 이러한 방법은 작업을 제자리에서 수행하고(자기 수정) 결과를 반환하려고 시도해야 합니다(자기일 수 있지만 그럴 필요는 없습니다).특정 메서드가 정의되지 않은 경우, 증강된 할당은 일반 메서드로 돌아갑니다.예를 들어, x가 다음을 가진 클래스의 인스턴스인 경우__iadd__()
방법,x += y
는 와동합다니등다에 합니다.x = x.__iadd__(y)
않으면 .그지않면으.x.__add__(y)
그리고.y.__radd__(x)
는 평가와 고려됩니다.x + y
특정 상황에서 할당이 증가하면 예기치 않은 오류가 발생할 수 있습니다(추가가 작동할 때 예외가 발생하는 이유는 무엇입니까? 참조). 그러나 이 동작은 실제로 데이터 모델의 일부입니다.
번째하는 것입니다.a
인플레이스를 사용하여 하는 것입니다.+=
교환입니다.
7.2.1에 대한 섹션을 참조하십시오. 증강된 할당 문:
▁▁express와 같은 증강된
x += 1
로 다시 쓸 수 있습니다.x = x + 1
유사하지만 정확하게 동일하지 않은 효과를 달성하기 위해.증강 버전에서 x는 한 번만 평가됩니다.또한 가능한 경우 실제 작업이 내부에서 수행되므로 새 개체를 생성하여 대상에 할당하는 대신 이전 개체가 수정됩니다.
+=
교환 전화이 함수는 변경을 인플레이스로 만들고 실행 후에만 결과가 "적용"하는 개체로 다시 설정됩니다.+=
온에
__add__
반면 매개 변수를 사용하여 합계를 반환합니다(수정하지 않음).
했듯이, 이미지듯이했적,이,b += 1
updates 보b
에, 자리에에반, 면제에.a = a + 1
산a + 1
합니다.a
결과적으로 (지금은)a
는 의행 의 행을 .A
더 이상).
이해기위해를 +=
연산자가 제대로 작동하지만, 우리는 또한 불변 대 불변 객체의 개념을 이해할 필요가 있습니다.우리가 그것을 빼먹었을 때 무슨 일이 일어나는지 생각해 보세요..reshape
:
C = np.arange(12)
for c in C:
c += 1
print(C) # [ 0 1 2 3 4 5 6 7 8 9 10 11]
우리는 그것을 봅니다.C
업데이트되지 않음, 즉c += 1
그리고.c = c + 1
동등합니다.왜냐하면 지금은C
배열1D 배입니다열(()입니다.C.ndim == 1
, 는 다음과 같이 합니다.C
의 정수 각의정요추출할고당됩다니되에 합니다.c
.
이며, 즉허용되지 않음을 하며, "Python"을 합니다.c += 1
안으로c = c + 1
서, 디에어c
이제는 에 결합되지 않은 새로운 정수를 나타냅니다.C
어떤 식으로든모양이 변경된 배열 위에 루프할 때 전체 행(np.ndarray
b
)a
) 한 번에, 그것은 당신이 자유롭게 새로운 정수에 고정할 수 있다는 것을 의미하는, 가변적인 객체이며, 당신이 그렇게 할 때 발생합니다.a += 1
.
하지만 언급해야 할 것은+
그리고.+=
한 바와 은 관련이 매우 많음) 방식으로 구현할 수 .__add__
각각 및 방법.
짧은 형식(a += 1
)에 수정할 수 있는 옵션이 있습니다.a
place는 객체를 만들어 ,a = a + 1
그래서,짧은형태(a += 1
)을가 없기 a
와는 달리a = a + 1
.
의 연산자이기 때문에 것을 : 또한동일결과출경별도연오서로시유십점하의에는다로.+
그리고.+=
우선: 는 루와의 a와 b를 가리킵니다.numpy.ndarray
물건들.
번째 번째루프서에첫,서,a = a + 1
.__add__(self, other)
의 numpy.ndarray
이 호출됩니다.그러면 새 개체가 생성되므로 A은(는) 수정되지 않습니다.다음에 변수 변, 수가 붙습니다.a
결과를 참조하도록 설정됩니다.
두 번째 루프에서는 새 개체가 생성되지 않습니다.b += 1
를 호출합니다.__iadd__(self, other)
의 numpy.ndarray
그것은 그것을 수정합니다.ndarray
b가 참조하는 제자리에 있는 객체.이런 이유로,B
수정되었습니다.
인 문제는 이 루프가 서중요문이제에행다루걸차음것반다입(1차원)의입니다.B
:
In [258]: B
Out[258]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [259]: for b in B:
...: print(b,'=>',end='')
...: b += 1
...: print(b)
...:
[0 1 2] =>[1 2 3]
[3 4 5] =>[4 5 6]
[6 7 8] =>[7 8 9]
[ 9 10 11] =>[10 11 12]
그므로러는+=
변형 가능한 개체인 배열에서 작동합니다.
이는 다른 답변에 포함되어 있지만, 만약 당신이 초점을 맞추면 쉽게 놓칩니다.a = a+1
또한 내부적으로 변경할 수 있습니다.b
와 함께[:]
더 것, 색화인더, 는멋진것또,것▁indexing는더멋▁fan,b[1:]=0
:
In [260]: for b in B:
...: print(b,'=>',end='')
...: b[:] = b * 2
[1 2 3] =>[2 4 6]
[4 5 6] =>[ 8 10 12]
[7 8 9] =>[14 16 18]
[10 11 12] =>[20 22 24]
물론 2D 어는이와 같은 합니다.B
우리는 보통 줄에서 반복할 필요가 없습니다.단일 운영 환경에서 작동하는 많은 작업B
전체적인 작업도 합니다.B += 1
,B[1:] = 0
타기.
언급URL : https://stackoverflow.com/questions/41446833/what-is-the-difference-between-i-i-1-and-i-1-in-a-for-loop
'programing' 카테고리의 다른 글
환경설정 활동에서 "자원에서 환경설정 추가" 대신 사용할 항목은 무엇입니까? (0) | 2023.08.09 |
---|---|
C# HashSet에 해당하는 JavaScript는 무엇입니까? (0) | 2023.08.09 |
보기의 배경색 설정 방법 (0) | 2023.08.09 |
Swift: 제네릭 형식이 프로토콜을 준수하는지 확인합니다. (0) | 2023.08.09 |
도커 용기 안에서 스도를 사용하는 방법은? (0) | 2023.08.09 |