列表理解中的Python怪异行为

时间:2013-12-11 03:53:16

标签: python-2.7

def nrooks(n):
    #make board
    print n # prints 4
    arr = [0 for n in range(n)] # if 0 for n becomes 0 for x, it works fine
    print n # prints 3 instead of 4

nrooks(4)

为什么第二个n变为3,与给定参数不同?

1 个答案:

答案 0 :(得分:4)

Python 2

列表推导中使用的n变量与传入的n相同。

理解将其设置为12,然后最终3

相反,将其更改为

arr = [0 for _ in range(n)]

或(令人惊讶!)

arr = list(0 for n in range(n))

Python 3

已修复此问题。

From the BDFL himself

  

我们还在Python 3中进行了另一项更改,以提高等效性   列表推导和生成器表达式之间。在Python 2中,   列表推导将循环控制变量“泄漏”到   周边范围:

x = 'before'
a = [x for x in 1, 2, 3]
print x # this prints '3', not 'before'
  

这是列表原始实现的工件   内涵;它是Python的“肮脏的小秘密”之一   年份。它最初只是故意妥协才能制作清单   理解力非常快,虽然这不是常见的陷阱   对于初学者来说,它偶尔会刺痛人们。对于发电机   表达式,我们不能这样做。生成器表达式   使用生成器实现,其执行需要单独的   执行框架......

     

但是,在Python 3中,我们决定修复“脏兮兮的小秘密”   通过使用与之相同的实施策略来列出理解   生成器表达式因此,在Python 3中,上面的例子(之后   修改使用print(x):-)将打印'before'。