저는 파이썬 파서를 만들고 있는데 이것은 정말 혼란 스럽습니다.
>>> 1 in [] in 'a'
False
>>> (1 in []) in 'a'
TypeError: 'in <string>' requires string as left operand, not bool
>>> 1 in ([] in 'a')
TypeError: 'in <string>' requires string as left operand, not list
연관성 등과 관련하여 Python에서 “in”이 정확히 어떻게 작동합니까?
이 두 표현이 같은 방식으로 작동하지 않는 이유는 무엇입니까?
답변
1 in [] in 'a'
로 평가됩니다 (1 in []) and ([] in 'a')
.
첫 번째 조건 ( 1 in []
)이 False
이므로 전체 조건은 다음과 같이 평가됩니다 False
. ([] in 'a')
실제로 평가되지 않으므로 오류가 발생하지 않습니다.
다음은 명령문 정의입니다.
In [121]: def func():
.....: return 1 in [] in 'a'
.....:
In [122]: dis.dis(func)
2 0 LOAD_CONST 1 (1)
3 BUILD_LIST 0
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 6 (in)
11 JUMP_IF_FALSE 8 (to 22) #if first comparison is wrong
#then jump to 22,
14 POP_TOP
15 LOAD_CONST 2 ('a')
18 COMPARE_OP 6 (in) #this is never executed, so no Error
21 RETURN_VALUE
>> 22 ROT_TWO
23 POP_TOP
24 RETURN_VALUE
In [150]: def func1():
.....: return (1 in []) in 'a'
.....:
In [151]: dis.dis(func1)
2 0 LOAD_CONST 1 (1)
3 LOAD_CONST 3 (())
6 COMPARE_OP 6 (in) # perform 1 in []
9 LOAD_CONST 2 ('a') # now load 'a'
12 COMPARE_OP 6 (in) # compare result of (1 in []) with 'a'
# throws Error coz (False in 'a') is
# TypeError
15 RETURN_VALUE
In [153]: def func2():
.....: return 1 in ([] in 'a')
.....:
In [154]: dis.dis(func2)
2 0 LOAD_CONST 1 (1)
3 BUILD_LIST 0
6 LOAD_CONST 2 ('a')
9 COMPARE_OP 6 (in) # perform ([] in 'a'), which is
# Incorrect, so it throws TypeError
12 COMPARE_OP 6 (in) # if no Error then
# compare 1 with the result of ([] in 'a')
15 RETURN_VALUE
답변
파이썬은 연결 비교로 특별한 일을합니다.
다음은 다르게 평가됩니다.
x > y > z # in this case, if x > y evaluates to true, then
# the value of y is being used to compare, again,
# to z
(x > y) > z # the parenth form, on the other hand, will first
# evaluate x > y. And, compare the evaluated result
# with z, which can be "True > z" or "False > z"
두 경우 모두 첫 번째 비교가 False
이면 나머지 문은 확인되지 않습니다.
특정 경우에
1 in [] in 'a' # this is false because 1 is not in []
(1 in []) in a # this gives an error because we are
# essentially doing this: False in 'a'
1 in ([] in 'a') # this fails because you cannot do
# [] in 'a'
또한 위의 첫 번째 규칙을 보여주기 위해 True로 평가되는 문입니다.
1 in [1,2] in [4,[1,2]] # But "1 in [4,[1,2]]" is False
2 < 4 > 1 # and note "2 < 1" is also not true
Python 연산자 우선 순위 : http://docs.python.org/reference/expressions.html#summary
답변
비교는 임의로 연결될 수 있습니다. 예를 들어 x <y <= z는 y가 한 번만 평가된다는 점을 제외하고 x <y <= z와 동일합니다 (그러나 두 경우 모두 x <y가 발견되면 z는 전혀 평가되지 않습니다. 거짓).
이것이 의미하는 것은 x in y in z
!에 연관성이 없다는 것입니다 .
다음은 동일합니다.
1 in [] in 'a'
# <=>
middle = []
# False not evaluated
result = (1 in middle) and (middle in 'a')
(1 in []) in 'a'
# <=>
lhs = (1 in []) # False
result = lhs in 'a' # False in 'a' - TypeError
1 in ([] in 'a')
# <=>
rhs = ([] in 'a') # TypeError
result = 1 in rhs
답변
짧은 대답은 긴 것이 이미 여러 번 주어 졌기 때문에 부울 표현식이 단락 되었다는 것입니다. 이것은 추가 평가에서 true 또는 그 반대로 변경 될 수없는 경우 평가를 중지 한 것입니다.
( http://en.wikipedia.org/wiki/Short-circuit_evaluation 참조 )
대답으로 약간 짧을 수도 있지만 (말장난이 아님) 언급했듯이 다른 모든 설명은 모두 여기에서 잘 수행되었지만 그 용어를 언급 할 가치가 있다고 생각했습니다.
답변
