joshuatvernon joshuatvernon - 27 days ago 9
Python Question

How to perform variable assignment within nested loops in python list comprehension

I would like to learn how to use list comprehension to find the things like the maximum value within a matrix.

This is a simplified version of what I'd like to do.

max_hourglass = 0
[[max_hourglass = i+j for j in range(4) if j < 3] for i in range(4)]
print(max)


I get a syntax error for the assignment of max. I tried casting
i
and
j
to integers just in case this was the problem, however, it doesn't appear to be the case.

The more complicated problem I'm attempting to use this code for is to solve a HackerRank question. I have already solved it, however, I am just attempting to expand my knowledge of
python3
by using different techniques to solve the problem. This is the Hackerrank problem.

Here is the more complicated problems code just in case the problem is different for it.

arr = []
for _ in range(6):
arr.append([int(num) for num in input().split()])

max_hourglass = 0
for i in range(4):
for j in range(4):
hourglass = arr[i][j] + arr[i][j+1] + arr[i][j+2] + arr[i+1][j+1] + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]
if hourglass > max_hourglass:
max_hourglass = hourglass
print(max_hourglass)


As you can see the problem I am trying to reduce to list comprehension is the nested for loops for which I came up with this code with the same logic as the simplified version:

[max_hourglass = (arr[i][j] + arr[i][j+1] + arr[i][j+2] + arr[i+1][j+1] + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]) for j in range(4) if (arr[i][j] + arr[i][j+1] + arr[i][j+2] + arr[i+1][j+1] + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]) > max_hourglass] for i in range(4)]


I'm completely aware this is less readable code and I would not use this in production but rather just want to further understand python's list comprehension syntax.

For context, the Hackerrank problem is to find in a 2D array (Matrix) the largest sum of values made up of the shape
I
of which they denote as an hourglass shape.

e.g.

1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0


Would result in the output
19
as the values:

2 4 4
2
1 2 4


add up to 19.

Answer

List comprehensions are supposed to be used to produce a list. Using them for some sort side effect is discouraged. And in your case of variable assignment, prohibited.

It is in effect a shorthand for

result = []
for ...:
    result.append(...)

If your problem does not fit that mold, it has no business being written as a list comprehension.

It is perfectly good form to construct several list comprehensions; and then apply some function like max to compress the list into one variable.

list1 = [.... for i in list0]
list2 = [.... for j in list1]
mymax = max(list2)

The lists could be replaced with generators and dictionary comprehensions.

Comprehensions encourage you to break the calculation into chunks or building blocks, which are then strung together into more complicated operations.