Python元组赋值和条件语句检查

时间:2014-03-16 00:24:52

标签: python python-2.7 if-statement tuples

所以我偶然发现python中元组的特定行为,我想知道是否有特定的原因发生了。

虽然我们完全有能力在没有变量的情况下为变量赋值 明确地将其括在括号中:

>>> foo_bar_tuple = "foo","bar"
>>> 

我们无法打印或签入包含变量的条件if语句 以前的方式的元组(没有明确地键入括号):

>>> print foo_bar_tuple == "foo","bar"
False bar

>>> if foo_bar_tuple == "foo","bar": pass
SyntaxError: invalid syntax
>>> 

>>> print foo_bar_tuple == ("foo","bar")
True
>>> 

>>> if foo_bar_tuple == ("foo","bar"): pass
>>>

有人为什么? 在此先感谢,虽然我没有找到任何类似的主题,但如果您认为这是一个可能的公告,请通知我。 干杯, 亚历

3 个答案:

答案 0 :(得分:7)

这是因为用逗号分隔的表达式在整个逗号分隔的元组之前被评估(这是Python语法术语中的“表达式列表”)。因此,当您执行foo_bar_tuple=="foo", "bar"时,会将其解释为(foo_bar_tuple=="foo"), "bar"the documentation中描述了此行为。

如果你只是自己编写这样一个表达式,你可以看到这个:

>>> 1, 2 == 1, 2  # interpreted as "1, (2==1), 2"
(1, False, 2)

未加密码化的元组的SyntaxError是因为未加粗体的元组在Python语法中不是“原子”,这意味着它不能作为if条件的唯一内容。 (您可以通过追踪the grammar来自行验证。)

答案 1 :(得分:4)

在[{3}}之后考虑if 1 == 1,2:应该导致SyntaxError的示例:

if 1 == 1,2:

使用if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite],我们可以转移if关键字并开始解析1 == 1,2:

对于test规则,只有第一次生产匹配:

test: or_test ['if' or_test 'else' test] | lambdef

然后我们得到:

or_test: and_test ('or' and_test)*

然后进入and_test

and_test: not_test ('and' not_test)*

此处我们暂时进入not_test

not_test: 'not' not_test | comparison

注意,我们的输入是1 == 1,2:,因此第一个产品不匹配,我们检查另一个:(1)

comparison: expr (comp_op expr)*

继续踩下(我们只选择第一个非终端,因为零或更多的星需要我们输入中根本没有的终端):

expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power

现在我们使用power制作:

power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_comp] ')' |
   '[' [testlist_comp] ']' |
   '{' [dictorsetmaker] '}' |
   NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')

并在我们的输入中转移NUMBER1)并减少。现在我们回到(1),输入==1,2:来解析。 ==匹配comp_op

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

所以我们转移并减少,留下输入1,2:(当前解析输出为NUMBER comp_op,我们现在需要匹配expr)。我们重复左侧的过程,直接进入atom非终端并选择NUMBER制作。转移并减少。

由于,comp_op不匹配,我们会减少test非终端并接收'if' NUMBER comp_op NUMBER。我们现在需要匹配elseelif:,但我们有,因此我们失败了SyntaxError

答案 2 :(得分:2)

I think the operator precedence table summarizes this nicely:

你会看到比较在表达式之前进行,这些表达式实际上已经死了。

in, not in, is, is not,                  Comparisons, including membership tests 
<, <=, >, >=, <>, !=, ==                 and identity tests

...

(expressions...), [expressions...],      Binding or tuple display, list display,
{key: value...}, `expressions...`        dictionary display, string conversion