2012-09-23 39 views
3

我很难理解为什么定义一个相同的条件语句在多个迭代列表中的理解会影响结果。条件语句在Python列表中的理解与多个迭代的定位

>>> boys = 'Jim','Jeff' 
>>> girls = 'Bonnie', 'Buffy' 

# This generates four tuples as expected 
>>> [(b,g) for b in boys for g in girls] 
[('Jim', 'Bonnie'), ('Jim', 'Buffy'), ('Jeff', 'Bonnie'), ('Jeff', 'Buffy')] 

# If the conditional "if b[-1] not in g" is at the end of the LC we get 3 
>>> [(b,g) for b in boys for g in girls if b[-1] not in g] 
[('Jim', 'Bonnie'), ('Jim', 'Buffy'), ('Jeff', 'Bonnie')] 

# If the conditional is after the first sequence, we only get two results 
>>> [(b,g) for b in boys if b[-1] not in g for g in girls] 
[('Jim', 'Bonnie'), ('Jim', 'Buffy')] 

如果其他人已经在StackOverflow上提出/回答了此问题,请事先道歉。

+1

我怀疑问题可能与优先级。 Parens解决歧义并恢复预期行为吗? –

+0

@BrianCain:这不是优先,它是LC的结构。 “if”放置在外部循环中,而不是第三个变体中的内部循环。 –

回答

3

你做什么是一样的:

>>> boys = 'Jim','Jeff' 
>>> girls = 'Bonnie', 'Buffy' 
>>> 
>>> out = [] 
>>> for b in boys: 
... for g in girls: 
...  out.append((b,g)) 
... 
>>> out 
[('Jim', 'Bonnie'), ('Jim', 'Buffy'), ('Jeff', 'Bonnie'), ('Jeff', 'Buffy')] 
>>> 
>>> out = [] 
>>> for b in boys: 
... for g in girls: 
...  if b[-1] not in g: 
...   out.append((b,g)) 
... 
>>> out 
[('Jim', 'Bonnie'), ('Jim', 'Buffy'), ('Jeff', 'Bonnie')] 
>>> 
>>> b 
'Jeff' 
>>> g 
'Buffy' 
>>> out = [] 
>>> for b in boys: 
...  if b[-1] not in g: 
...   for g in girls: 
...   out.append((b,g)) 
... 
>>> out 
[('Jim', 'Bonnie'), ('Jim', 'Buffy')] 

由于bg已经定义并从上次运行填充值时,会发生以下情况:

  • 第一外环Jim
    • m in Buffy?否 - 运行内部循环:
    • 追加(Jim, Bonnie)
    • 追加(Jim, Buffy)
  • 第二外环Jeff
    • Buffyf?是 - 跳过内部循环。

如果你在运行这个首次在 Python的外壳,它会引发Exception

>>> # b = g = None 
>>> boys = 'Jim','Jeff' 
>>> girls = 'Bonnie', 'Buffy' 
>>> 
>>> [(b,g) for b in boys if b[-1] not in g for g in girls] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <listcomp> 
UnboundLocalError: local variable 'g' referenced before assignment 
+0

谢谢Tim!非常清楚地解释。 – damzam