programing

'for' 루프에서 i = i + 1과 i + = 1의 차이는 무엇입니까?

i4 2023. 8. 9. 20:30
반응형

'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 += 1updates 보b에, 자리에에반, 면제에.a = a + 1a + 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.ndarrayb)a) 한 번에, 그것은 당신이 자유롭게 새로운 정수에 고정할 수 있다는 것을 의미하는, 가변적인 객체이며, 당신이 그렇게 할 때 발생합니다.a += 1.

하지만 언급해야 할 것은+그리고.+=한 바와 은 관련이 매우 많음) 방식으로 구현할 수 .__add__각각 및 방법.

짧은 형식(a += 1)에 수정할 수 있는 옵션이 있습니다.aplace는 객체를 만들어 ,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그것은 그것을 수정합니다.ndarrayb가 참조하는 제자리에 있는 객체.이런 이유로,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

반응형