Reputation: 643
I expected the following 2 code-segments to be essentially equivalent.
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]
The one with the for-loops is "correct" (thats what I wanted). Why did the list comprehension-version swap the indexes?
Upvotes: 1
Views: 77
Reputation: 1121744
You have your loops inverted in the first version. You are creating inner tuples looping over range(len(avail))
and outer tuples with a loop over range(len(avail[i]))
.
Your code is the equivalent (with lists instead of tuples) of this instead:
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)
and relied on i
still being assigned as a global. You can see this too when you indent your expression based on the parenthesis:
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]))
)
Reverse the loops (indented differently to communicate the grouping better):
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)))
The above is the equivalent of:
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)
You can simplify your code with using enumerate()
:
return tuple(
tuple(False if (i,j) in neighborhood else v for j, v in enumerate(row))
for i, row in enumerate(avail))
Upvotes: 1