什么是正确的写这个列表理解的方式?

时间:2010-09-27 11:11:50

标签: python list-comprehension

我收到错误:name 'i' is not defined

k = [ [ rids[i][j][0]['a'] * rids[i][j][1]['b']  for i in range(0,10) ] 
     for j in range(0,len(furs[i])) ]

但是

k = [ rids[i][j][0]['a'] * rids[i][j][1]['b']   for i in range(0,10)  
     for j in range(0,len(furs[i])) ]

令人惊讶地工作!

编辑:编写它们的正确方法是什么?我正在尝试生成一个二维矩阵,其中i作为外部for循环和迭代的迭代器。 j作为内部for循环的迭代器。

3 个答案:

答案 0 :(得分:1)

在您的第一个示例中

for j in range(0,len(furs[i])):由于前面的i]不在此范围内。

答案 1 :(得分:1)

仔细查看第二个for循环:for j in range(0,len(furs[i]))。您在此处引用i,即使它是在前面的第一个列表推导([ rids[i][j][0]['a'] * rids[i][j][1]['b'] for i in range(0,10) ])中创建和使用的。

i仅限于第一次理解的范围;因此,第二种理解是不可见的。因此,您会收到错误。

第二种变体有效,因为ij都在相同的列表理解中声明并使用。

让我们稍微简化一下片段。试试这个:

>>> [ [ i * j  for i in range(0,10) ] for j in range(0, i) ]

Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    [ [ i * j  for i in range(0,10) ] for j in range(0, i) ]
NameError: name 'i' is not defined
>>> 

现在结合理解,从而将ij放在同一范围内:

>>> [ i * j   for i in range(0,10)  for j in range(0, i) ]
[0, 0, 2, 0, 3, 6, 0, 4, 8, 12, 0, 5, 10, 15, 20, 0, 6, 12, 18, 24, 
 30, 0, 7, 14, 21, 28, 35, 42, 0, 8, 16, 24, 32, 40, 48, 56, 0, 9, 
 18, 27, 36, 45, 54, 63, 72]
>>> 

现在(厚脸皮= P)再次尝试第一次理解:

>>> [ [ i * j  for i in range(0,10) ] for j in range(0, i) ]
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18], [0, 3, 6, 9, 12, 15, 18, 21, 24, 27], 
 [0, 4, 8, 12, 16, 20, 24, 28, 32, 36], [0, 5, 10, 15, 20, 25, 30, 35, 40, 45], 
 [0, 6, 12, 18, 24, 30, 36, 42, 48, 54], [0, 7, 14, 21, 28, 35, 42, 49, 56, 63], 
 [0, 8, 16, 24, 32, 40, 48, 56, 64, 72]]
>>> 
塔达!它有效,但提供不同的结果。为什么会这样?原因是{em}(最后)值i 在示例二之后的最外层范围内可用。也就是说,在列表推导中创建的变量在REPL范围内可用。

(PS:我相信上面的段落可以改写。更好的Pythonistas,请帮帮忙)

要验证这一点,请尝试删除i并再次运行示例3.

>>> del i
>>> [ [ i * j  for i in range(0,10) ] for j in range(0, i) ]

Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    [ [ i * j  for i in range(0,10) ] for j in range(0, i) ]
NameError: name 'i' is not defined
>>> 

我们又回到原点。

答案 2 :(得分:0)

k = [ [ rids[i][j][0]['a'] * rids[i][j][1]['b']
for i in range(0,10) ] for j in range(0,len(furs[i])) ]
在上面的陈述中,我只存在于第一个]之后,i在此之后超出了范围。