2016-09-30 49 views
2

我在学习列表推导,并且通过切换变量得到2个不同的结果,尽管它们看起来应该是一样的。当在列表理解中对语句重新排序时NameError

阵列a等于[[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

列表综合1部作品:

[(i,j) for j in range(len(a[i])) for i in range(len(a))] 

返回:

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)] 

正如所预期的。

但翻转变量...

[(j,i) for i in range(len(a[j])) for j in range(len(a))] 

导致NameError:没有定义

名“J”可有人请向我解释为什么它的事项i或j是否是第一位的?

回答

4

这并不是说这里重要的变量的顺序。事实上,出于与列表理解2相同的原因,运行列表理解1也是行不通的。我猜你在程序的前面定义了i,这就是为什么列表理解1适合你。问题是for循环的顺序。

我会尝试通过示例来解释。如果你这样写,它会运行良好:

[ [(i,j) for j in range(len(a[i]))] for i in range(len(a))] 

请注意我添加的方括号。在这种情况下,for回路与i首先发生,然后forj回路。 (但应该指出,这将返回元组列表的列表。)或者,这也将运行良好:

[(i,j) for i in range(len(a)) for j in range(len(a[i]))] 

当两个for环路写在一起的方式(没有多余的括号这个时候),他们正在读左到右。

+0

你应该提到你的第一个例子,嵌套列表comp,创建了元组列表的列表。或者只是将它的输出包含在你的答案中。 –

+1

好的是有道理的,所以在第一个例子中,括号后面的for循环是第一个运行的吗?例如,如果'ninecells = [[a [0] [0] + w,a [0] [1] + h]在范围(-1,2)中对于范围(-1,2)中的w, '那么'范围内的h'将首先运行? – st4rgut

+0

@ PM2Ring好点,补充说。 – Meerness

6

如果在单个列表理解中有一个双重for循环,则它等同于使用“传统”for循环以相同顺序执行那些for循环。所以

result = [(j,i) for i in range(len(a[j])) for j in range(len(a))] 

是(几乎完全)等同于

result = [] 
for i in range(len(a[j])): 
    for j in range(len(a)): 
     result.append((j, i)) 

正如你所看到的,当你做len(a[j])变量j不存在,这就是为什么你会得到NameError

顺便说一句,你的第一个列表比较不应该工作。我怀疑你的代码早些时候定义了i,这就是为什么你没有得到NameError。下面是该列表组件的一个稍微改进的版本,它假定a是一个矩阵,即它的所有子列表都是相同的长度,并且它至少包含一个子列表。

[(i,j) for j in range(len(a[0])) for i in range(len(a))] 

我们也可以做

[(j, i) for i in range(len(a)) for j in range(len(a[0]))] 

的这两项列表谱曲创建此列表:

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)] 
+0

注意:既不listcap应该工作,我怀疑全局或嵌套范围虽然定义了一个名为'i'的变量,并且由于矩阵是'nxn',只要'i'是一个合法的索引,它的用途(计算“范围”的长度)即使它没有按正确的顺序工作。 – ShadowRanger

+0

@ShadowRanger:是的,我只是注意到了我自己。 :)我会在我的答案中提到这一点。 –