1

我预计以下 2 个代码段基本上是等效的。

return tuple(tuple( False if (i,j) in neighborhood else avail[i][j]
    for i in range(len(avail)))     
    for j in range(len(avail[i])))

(False, False, True, True, True)
(False, False, True, True, True)
(False, False, True, True, True)
(False, False, True, True, True)
(True, True, True, True, True)

ls = [[val for val in row] for row in avail]
for i in range(len(avail)):
    for j in range(len(avail[i])):
        if (i,j) in neighborhood:
            ls[i][j] = False
return ls

[False, False, False, False, True]
[False, False, False, False, True]
[True, True, True, True, True]
[True, True, True, True, True]
[True, True, True, True, True]

带有 for 循环的那个是“正确的”(这就是我想要的)。为什么列表理解版本交换索引?

4

1 回答 1

1

您在第一个版本中反转了循环。您正在创建循环的内部元range(len(avail))组和带有循环的外部元组range(len(avail[i]))

您的代码与此等效(使用列表而不是元组):

outer = []
for j in range(len(avail[i])):
    inner = []
    for i in range(len(avail)):
        inner.append(False if (i,j) in neighborhood else avail[i][j])
    outer.append(inner)

并依靠i仍然被分配为全局。当您根据括号缩进表达式时,您也可以看到这一点:

return tuple(
    tuple(
        False if (i,j) in neighborhood else avail[i][j]
        for i in range(len(avail))
    )     
    for j in range(len(avail[i]))
)

反转循环(缩进不同以更好地传达分组):

return tuple(
    tuple(False if (i,j) in neighborhood else avail[i][j] for j in range(len(avail[i])))     
    for i in range(len(avail)))

以上等价于:

outer = []
for i in range(len(avail)):
    inner = []
    for j in range(len(avail[i])):
        inner.append(False if (i,j) in neighborhood else avail[i][j])
    outer.append(inner)

您可以使用以下方法简化代码enumerate()

return tuple(
    tuple(False if (i,j) in neighborhood else v for j, v in enumerate(row))    
    for i, row in enumerate(avail))
于 2013-08-07T13:14:38.980 回答