답변:
이해가되지 않기 때문이 아닙니다. "x ++"를 "x + = 1로 정의하여 x의 이전 바인딩으로 평가"하는 것이 좋습니다.
원래의 이유를 알고 싶다면 오래된 파이썬 메일 링리스트를 살펴 보거나 거기에 있던 누군가에게 물어봐야합니다 (예 : 귀도). 그러나 사실 이후 정당화하기는 쉽습니다.
다른 언어만큼 간단한 증감이 필요하지 않습니다. for(int i = 0; i < 10; ++i)
파이썬 과 같은 것을 자주 쓰지 않습니다 . 대신 당신은 같은 일을 for i in range(0, 10)
합니다.
거의 자주 필요하지 않기 때문에 고유 한 구문을 제공 할 이유가 훨씬 적습니다. 증분해야 할 때 +=
일반적으로 괜찮습니다.
그것이 의미가 있는지, 할 수 있는지, 할 수 있는지, 할 수 있는지에 대한 결정은 아닙니다. 이점이 언어의 핵심 구문에 추가 할 가치가 있는지에 대한 질문입니다. 이것은 postinc, postdec, preinc, predec의 네 가지 연산자이며 각각의 클래스 오버로드가 필요합니다. 그것들은 모두 명시되고 테스트되어야한다. 언어에 opcode를 추가합니다 (더 큰 VM 엔진을 의미 함). 논리적 증가를 지원하는 모든 클래스는 (위에이를 구현해야 +=
하고 -=
).
이 모두와 +=
와 중복 -=
되므로 순손실이됩니다.
i
직접 루프를 반복 할 수도 있습니다. 실제로 필요할 때 사용할 수없는 경우array.append()
i++
과 ++i
... 사이의 구별에 대한 오해에서 비롯된 충분한 버그 이상을 보았습니다 .
++
과 --
같은 방법으로 사용되는 정의되지 않았거나 지정되지 않은 결과가 행동. 복잡하고 수정하기 어려운 구문 분석 코드를 작성할 수 있습니다.
내가 쓴이 원래의 대답은 컴퓨팅 민속학의 신화입니다. Dennis Ritchie 가 ACM 커뮤니케이션 편집자에게 보낸 편지에서 2012 년 7 월 doi : 10.1145 / 2209249.2209251에 언급 된 것처럼 "역사적으로 불가능하다"고 주장했습니다.
C 증분 / 감소 연산자는 C 컴파일러가 똑똑하지 않은 시점에 발명되었으며 저자는 기계 언어 연산자를 사용해야하는 직접적인 의도를 지정할 수 있기를 원했습니다. 할 수 있습니다
load memory
load 1
add
store memory
대신에
inc memory
PDP-11 은 각각 *++p
및에 해당하는 "자동 증가"및 "자동 증가 지연"명령도 지원 *p++
했습니다. 몹시 호기심이 많으면 설명서 의 섹션 5.3을 참조하십시오 .
컴파일러는 C 구문에 내장 된 고급 최적화 트릭을 처리 할 수있을만큼 똑똑하기 때문에 지금은 구문상의 편의에 불과합니다.
파이썬에는 의도를 사용하지 않기 때문에 의도를 어셈블러에 전달하는 트릭이 없습니다.
나는 항상 파이썬의이 선과 관련이 있다고 가정했습니다.
이를 수행 할 수있는 분명한 방법은 하나만 있어야합니다.
x ++와 x + = 1은 똑같은 작업을 수행하므로 둘 다 가질 이유가 없습니다.
one--
0입니까?
one--
문장에서 하나이지만 바로 뒤에 0입니다. 따라서이 '관념'은 증가 / 감소 연산자가 명백하지 않다는 것을 암시합니다.
물론 우리는 "Guido가 그렇게 결정했다"고 말할 수는 있지만, 그 결정에 대한 이유는 문제라고 생각합니다. 몇 가지 이유가 있다고 생각합니다.
파이썬에서 정수는 불변이기 때문에 (int의 + =는 실제로 다른 객체를 반환합니다).
또한 ++ /-를 사용하면 사전 및 사후 증분 / 감소에 대해 걱정할 필요가 있으며 키를 한 번 더 입력하면 x+=1
됩니다. 다시 말해, 이득이 거의 없어도 혼동을 피할 수 있습니다.
42++
... 이것 (리터럴 상수 수정) 은 오래된 Fortran 컴파일러에서 실제로 가능했습니다 (또는 읽었습니다) : 모든 향후 사용 해당 프로그램 실행에서 해당 리터럴의 값은 실제로 다른 값을 갖습니다. 행복한 디버깅!
int
일반적으로 C 가 불변 인 것은 아닙니다 . int
C에서 단순히 메모리에있는 장소를 지정합니다. 그리고 그 장소의 비트는 매우 변경 가능합니다. 예를 들어의 참조를 만들고 해당 참조의 참조를 int
변경할 수 있습니다. 이 변경 사항은 int
해당 위치에 대한 모든 참조 (원래 변수 포함)에서 볼 수 있습니다 . 파이썬 정수 객체도 마찬가지입니다.
파이썬은 명확성 에 대해 많은 것이 있으며, --a
그 구조를 가진 언어를 배우지 않으면 프로그래머가 그 의미를 정확하게 추측하지 못할 것 입니다.
파이썬은 또한에 대해 많은입니다 실수를 초대 구조 피 와 ++
운영자가 결함의 풍부한 소스 것으로 알려져됩니다. 이 두 가지 이유는 파이썬에서 그 연산자를 갖기에 충분하지 않습니다.
파이썬이 들여 쓰기를 사용하여 시작 / 종료 브라케팅 또는 필수 끝 표시와 같은 구문 적 수단보다는 블록을 표시한다는 결정은 대체로 동일한 고려 사항을 기반으로합니다.
예를 들어, 2005 년 에 조건부 연산자 (C cond ? resultif : resultelse
:)를 파이썬에 도입하는 것에 관한 토론을 살펴 보십시오. 적어도 첫 번째 메시지를 읽으십시오. 그 토론 와 결정 메시지 (이전에 동일한 주제에 대해 여러 개의 선구자가 있음 .
퀴즈 : 자주 언급되는 PEP는 "Python Extension Proposal" PEP 308 입니다. LC는 list comprehension을 의미 하고 GE는 generator expression을 의미 합니다 (그리고 혼동하더라도 걱정할 필요가 없습니다. 파이썬의 복잡한 부분은 아닙니다).
파이썬에 ++
연산자가 없는 이유에 대한 나의 이해 는 다음과 같습니다. 파이썬으로 이것을 작성할 때 a=b=c=1
동일한 객체 (값 1)를 가리키는 세 개의 변수 (라벨)가 나타납니다. 객체 메모리 주소를 반환하는 id 함수를 사용하여이를 확인할 수 있습니다.
In [19]: id(a)
Out[19]: 34019256
In [20]: id(b)
Out[20]: 34019256
In [21]: id(c)
Out[21]: 34019256
세 가지 변수 (라벨)는 모두 같은 객체를 가리 킵니다. 이제 변수 중 하나를 증가시키고 그것이 메모리 주소에 어떻게 영향을 미치는지보십시오 :
In [22] a = a + 1
In [23]: id(a)
Out[23]: 34019232
In [24]: id(b)
Out[24]: 34019256
In [25]: id(c)
Out[25]: 34019256
a
변수가 변수 b
및 로 다른 객체를 가리키는 것을 볼 수 있습니다 c
. 당신이 a = a + 1
그것을 사용했기 때문에 분명합니다. 다시 말해 label에 완전히 다른 객체를 할당합니다 a
. a++
변수에 할당하지 않았다고 제안 할 수 있다고 상상해보십시오.a
새 객체에 오래된 객체를 래터 증가 시킨다는 . 이 모든 것은 혼란을 최소화하기위한 IMHO입니다. 더 잘 이해하려면 파이썬 변수의 작동 방식을 참조하십시오.
파이썬에서 함수가 호출자가 인식 한 일부 인수를 수정할 수 있지만 다른 인수는 수정할 수없는 이유는 무엇입니까?
파이썬은 값에 의한 호출입니까, 아니면 참조에 의한 호출입니까? 둘 다.
그것은 단지 그런 식으로 설계되었습니다. 증가 및 감소 연산자는 바로 가기입니다 x = x + 1
. 파이썬은 일반적으로 작업을 수행하는 대체 수단의 수를 줄이는 설계 전략을 채택했습니다. 확장 할당 은 파이썬에서 연산자를 증가 / 감소시키는 가장 가까운 것이며, 파이썬 2.0까지 추가되지 않았습니다.
return a[i++]
있습니다 return a[i=i+1]
.
첫째, 파이썬은 C에 의해서만 간접적으로 영향을받습니다. ABC에 크게 영향을받으며 , 이러한 연산자 는없는 것 같습니다. 따라서 파이썬에서도 찾을 수 없다는 것은 놀라운 일이 아닙니다.
둘째, 다른 사람들이 말했듯이 증가 및 감소는 +=
및-=
이미.
셋째, ++
및--
연산자 집합에 에는 일반적으로 접두사 및 접미사 버전을 모두 지원하는 것이 포함됩니다. C와 C ++에서 이것은 모든 종류의 "사랑스러운"구성체가 파이썬이 받아들이는 단순성과 직설 성의 정신에 위배되는 것처럼 보일 수 있습니다.
예를 들어, C 문 while(*t++ = *s++);
은 숙련 된 프로그래머, 그것을 배우는 사람에게는 단순하고 우아하게 보일 수 있지만 간단합니다. 접두사와 접두사 증가 및 감소를 혼합하여 던져보십시오. 심지어 많은 전문가들도 그만두고 조금 생각해야합니다.
나는 그것이 "명시적인 것이 묵시적인 것보다 낫다"는 파이썬 신조에서 나온 것이라고 믿는다.
@GlennMaynard 가 다른 언어와 비교하여 문제를보고 있기 때문일 수 있지만 파이썬에서는 파이썬 방식으로 일을합니다. '왜'질문이 아닙니다. 거기에 있으며와 같은 효과를 낼 수 있습니다 x+=
. 에서 파이썬의 선 , 주어진 : "만 문제를 해결하는 하나 개의 방법이 있어야한다." 객관식은 예술 (표현의 자유)에서는 훌륭하지만 공학에서는 까다 롭습니다.
++
사업자의 클래스는 부작용 표현입니다. 이것은 일반적으로 파이썬에서 찾을 수없는 것입니다.
같은 이유로 할당은 파이썬에서 표현식이 아니므로 일반적인 if (a = f(...)) { /* using a here */ }
관용구를 막습니다.
마지막으로 연산자가 파이썬 참조 의미와 매우 일치하지 않는 것으로 생각됩니다. 파이썬에는 C / C ++에서 알려진 의미론을 가진 변수 (또는 포인터)가 없습니다.
f(a)
있는 a
것은 없습니다.
이 연산자가 왜 C에 존재하는지 묻는 것이 더 좋은 질문 일 것입니다. 서론은 그것들을 '더 간결하고 종종 더 효율적'이라고 부릅니다. 이러한 조작이 항상 포인터 조작에서 발생한다는 사실이 도입에 일부 영향을 미쳤다고 생각합니다. 파이썬에서는 증분 최적화를 시도하는 것이 타당하지 않다고 결정되었을 것입니다 (사실 C에서 테스트를 수행했으며 gcc 생성 어셈블리는 두 경우를 모두 포함하지 않고 addl을 사용하는 것 같습니다) 포인터 산술; 그래서 그것은 한 가지 더 할 수있는 방법 일 것입니다. 우리는 파이썬이 그것을 싫어한다는 것을 알고 있습니다.
해당 페이지에서 이미 좋은 답변을 완료하려면 다음 단계를 따르십시오.
++i
단항 + 및-연산자를 손상시키는 접두사 ( )를 사용 하기로 결정했다고 가정 해 봅시다 .
오늘날에 의해 접두사 ++
또는 --
두 번이 단항 플러스 연산자를 수 있기 때문에, 아무것도하지 않는 두 번이나 단항 마이너스 (아무것도하지 않는다) (2 회 : 자체를 취소)
>>> i=12
>>> ++i
12
>>> --i
12
그래서 그것은 아마도 그 논리를 깨뜨릴 것입니다.
나는 이것이 객체의 가변성과 불변성의 개념과 관련이 있다고 생각합니다. 2,3,4,5는 파이썬에서 불변입니다. 아래 이미지를 참조하십시오. 이 파이썬 프로세스까지 2는 고정 ID입니다.
x ++는 본질적으로 C와 같은 인플레 이스 증분을 의미합니다. C에서 x ++는 인플레 이스 증분을 수행합니다. 따라서 3은 여전히 메모리에 존재하는 파이썬과 달리 x = 3이고 x ++는 메모리에서 3을 4로 증가시킵니다.
따라서 파이썬에서는 메모리에 값을 다시 만들 필요가 없습니다. 이것은 성능 최적화로 이어질 수 있습니다.
이것은 직감 기반의 답변입니다.
나는 이것이 오래된 스레드라는 것을 알고 있지만 ++ i의 가장 일반적인 사용 사례는 제공되지 않습니다. 제공된 인덱스가 없을 때 수동으로 세트를 인덱싱하는 것입니다. 이 상황에서 파이썬은 enumerate ()를 제공합니다
예 : 어떤 언어로든 foreach와 같은 구문을 사용하여 집합을 반복 할 때-예제를 위해 순서가 지정되지 않은 집합이라고 말하고 모든 것을 구별하기 위해 고유 한 색인이 필요합니다.
i = 0
stuff = {'a': 'b', 'c': 'd', 'e': 'f'}
uniquestuff = {}
for key, val in stuff.items() :
uniquestuff[key] = '{0}{1}'.format(val, i)
i += 1
이 경우 파이썬은 열거 방법을 제공합니다.
for i, (key, val) in enumerate(stuff.items()) :