Python различает выражения , которые оценивают значение, от операторов (инструкции), которые этого не делают.Любое выражение может использоваться в качестве оператора в Python (как выражение выражения), в этом случае значение просто отбрасывается.Другие типы операторов могут содержать выражения, а выражения могут содержать подвыражения.
r = (1 if v in c.values() else 0)
не является ни выражением, ни даже выражением.Это оператор присваивания .
Справа этот оператор присваивания содержит условное выражение (1 if v in c.values() else 0)
, содержащее три подвыражения
- a Сравнение выражение
v in c.values()
, - a литерал целое число
1
и - буквальное целое число
0
.
Сравнения оценивают как bool и имеют более сложные правила оценки, чем простые арифметические операторы, потому что они могут быть связаны.Это сравнение использует только один оператор in
и содержит два подвыражения:
Выражение вызова содержит ссылку на атрибут primary c.values
.Это считается подвыражением выражения вызова.
Вы можете точно увидеть, как Python анализирует это, используя модуль ast
.
>>> import ast
>>> print(ast.dump(compile('r = (1 if v in c.values() else 0)', '<str>', 'exec', ast.PyCF_ONLY_AST)))
Module(body=[Assign(targets=[Name(id='r', ctx=Store())], value=IfExp(test=Compare(left=Name(id='v', ctx=Load()), ops=[In()], comparators=[Call(func=Attribute(value=Name(id='c', ctx=Load()), attr='values', ctx=Load()), args=[], keywords=[])]), body=Num(n=1), orelse=Num(n=0)))])
Этонемного трудно читать в одной строке.Здесь это переформатировано.Я также удалил обертку модуля, созданную компиляцией, которая не имеет отношения к этому обсуждению.
Assign(
targets=[Name(id="r", ctx=Store())],
value=IfExp(
test=Compare(
left=Name(id="v", ctx=Load()),
ops=[In()],
comparators=[
Call(
func=Attribute(
value=Name(id="c", ctx=Load()), attr="values", ctx=Load()
),
args=[],
keywords=[],
)
],
),
body=Num(n=1),
orelse=Num(n=0),
),
)