집합 리터럴은 집합 함수 호출과 다른 결과를 제공합니다.
set
함수 호출은 중복을 지우지 만 집합 리터럴을 구문 분석하지 않는 이유는 무엇 입니까?
>>> x = Decimal('0')
>>> y = complex(0,0)
>>> set([0, x, y])
{0}
>>> {0, x, y}
{Decimal('0'), 0j}
(Python 2.7.12. 이 유사한 질문과 동일한 근본 원인 일 수 있음 )
동등성을위한 테스트를 설정하고, 새로운 Python 릴리스가 나올 때까지이 작업을 수행하는 순서는 아래에서 설명하는 것처럼 생성중인 세트에 값을 전달하는 형식에 따라 다를 수 있습니다.
때문에 0 == x
사실 과 0 == y
사실이지만 x == y
이고 거짓 , 여기에 행동은 정말 정의되지 않은 세트가 그 가정으로, x == y
처음 두 시험이 너무 사실이라면 참이어야합니다.
에 전달 된 목록 을 반대로 하면 set()
동등성 테스트의 순서가 변경되므로 리터럴을 사용하는 것과 동일한 출력을 얻을 수 있습니다.
>>> set([y, x, 0])
set([0j, Decimal('0')])
리터럴을 뒤집는 경우에도 동일합니다.
>>> {y, x, 0}
set([0])
무슨 일이 일어나고 있는지 집합 리터럴 이 값을 스택에로드 한 다음 스택 값이 새 집합 개체에 역순으로 추가됩니다.
긴만큼 0
로드 첫째 , 다른 두 개체가 다음에 대해 테스트 0
세트에 이미. 다른 두 개체 중 하나가 먼저로드되는 순간 동등성 테스트가 실패하고 두 개체가 추가됩니다.
>>> {y, 0, x}
set([Decimal('0'), 0j])
>>> {x, 0, y}
set([0j, Decimal('0')])
그 세트 리터럴이 역순으로 요소를 추가하는 것은 Python 2.7.12 및 3.5.2까지 구문을 지원하는 모든 버전의 Python에 존재하는 버그입니다. 최근에 수정되었습니다. 문제 26020 (2.7.13, 3.5.3 및 3.6의 일부, 아직 릴리스 된 항목 없음)을 참조하세요. 당신은 2.7.12을 보면, 당신은 볼 수 있습니다 BUILD_SET
에서ceval.c
아래로 위로부터 스택을 읽
# oparg is the number of elements to take from the stack to add
for (; --oparg >= 0;) {
w = POP();
if (err == 0)
err = PySet_Add(x, w);
Py_DECREF(w);
}
바이트 코드가 역순으로 스택에 요소를 추가하는 동안 ( 0
스택을 먼저 푸시 ) :
>>> from dis import dis
>>> dis(compile('{0, x, y}', '', 'eval'))
2 0 LOAD_CONST 1 (0)
3 LOAD_GLOBAL 0 (x)
6 LOAD_GLOBAL 1 (y)
9 BUILD_SET 3
12 RETURN_VALUE
수정 사항은 스택에서 요소를 역순으로 읽는 것입니다. 파이썬 2.7.13 버전을 사용하는 PEEK()
대신에 POP()
(그리고는 STACKADJ()
나중에 스택의 요소를 제거하기 위해) :
for (i = oparg; i > 0; i--) {
w = PEEK(i);
if (err == 0)
err = PySet_Add(x, w);
Py_DECREF(w);
}
STACKADJ(-oparg);
동등성 테스트 문제는 다른 질문과 동일한 근본 원인을 가지고 있습니다. Decimal()
클래스는 몇 가지 평등 문제를 가지고있다 complex
(하여 파이썬 3.2에서 수정되었습니다 여기 Decimal()
에 지원 비교를 complex
하고 이전에 지원하지 않은 몇 가지 다른 숫자 유형 ).
세트가 구성되는 순서에 따라 다른 질문 과 함께 발견 한 버그가 결합됩니다 . 리터럴은 목록에서 변환하는 것과 반대 순서로 구성되는 것으로 보입니다.
>>> {0, x, y}
set([0j, Decimal('0')])
>>> {y, x, 0}
set([0])
'UFO ET IT' 카테고리의 다른 글
C 컴파일러는 어떻게 C로 작성할 수 있습니까? (0) | 2020.12.31 |
---|---|
"문자열"이 "문자열"의 단순화 된 버전으로 간주되는 이유는 무엇입니까? (0) | 2020.12.31 |
Joda 시간 : 요일? (0) | 2020.12.31 |
Windows 마지막 재부팅 이유를 어떻게 알 수 있습니까? (0) | 2020.12.31 |
GIT 경고 : 부정확 한 이름 변경 감지를 건너 뛰는 파일이 너무 많습니다. (0) | 2020.12.31 |