简体   繁体   中英

How to understand the Python code I wrote for a problem

If I give 2 output is

2 2 2
2 1 2
2 2 2

and for 3 is

3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3

The code is as follows:

def square(arr, val):

    if val is 1:
        return [[1]]    //self understandable

    n = val + (val - 1)       //getting array size, for 2 its 3

    sideAdd = [val] * n              
    arr.insert(0, sideAdd)      //for 2 it add [2,2,2] at first
    arr.append(sideAdd)         //append [2,2,2]

    for i in range(1, n-1):      //for inner elements add val to either sides
        arr[i].insert(0, val)    // like, for 2 [val,1,val]
        arr[i].append(val)


    return(arr)


array = square([[2, 2, 2], [2, 1, 2], [2, 2, 2]], 3)


# print(array)
for i in array:
    print(*i)

The output goes like:

3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3

which is a correct answer.

But when I tried to complete the whole solution by giving values through for loop and sending returned array as parameter again through the same function like

n = 3  
arr = []

for i in range(1, n+1):

    arr = square(arr, i)

the whole code is

def square(arrx, val):

    if val is 1:
        return [[1]]

    n1 = val + (val - 1)

    sideAdd = [val] * n1
    arrx.insert(0, sideAdd)
    arrx.append(sideAdd)


    for i in range(1, n1-1):
        arrx[i].insert(0, val)
        arrx[i].append(val)

    return arrx


n = 3
arr = []

for i in range(1, n+1):

    arr = square(arr, i)



for i in arr:
    print(*i)

This returns the answer as:

3 3 3 3 3
3 3 2 2 2 3 3
3 2 1 2 3
3 3 2 2 2 3 3
3 3 3 3 3

which is wrong

I already tried running in debug mode in pycharm, there I got an unusual thing. Check the screenshot below. When j = 1 (index), the code inserts 2 in blue underline but also in red which should not because the red underline index is 3 (insertion of 2 should occur at j = 3), and when j = 3 again insertion at index 1 (j = 1) is happening which makes the output 3 3 2 2 2 3 3 instead of 3 2 2 2 3.

I can't understand how that's happening. The screenshot is as follows:

https://imgur.com/yce47Pi

I think you are making this more complicated than it needs to be. You can determine the correct value of any cell from their indexes alone. Given a size n and row/column [i,j] , the value is:

max(abs(n - 1 - j) + 1, abs(n - 1 - i) + 1)

For example:

def square(n):
    arr = []

    for i in range(n + n-1):
        cur = []
        arr.append(cur)
        for j in range(n + n -1):
            cur.append(max(abs(n - 1 - j) + 1, abs(n - 1 - i) + 1))
    return arr

Then

> square(3)  

[[3, 3, 3, 3, 3],
 [3, 2, 2, 2, 3],
 [3, 2, 1, 2, 3],
 [3, 2, 2, 2, 3],
 [3, 3, 3, 3, 3]]

> square(5)

[[5, 5, 5, 5, 5, 5, 5, 5, 5],
 [5, 4, 4, 4, 4, 4, 4, 4, 5],
 [5, 4, 3, 3, 3, 3, 3, 4, 5],
 [5, 4, 3, 2, 2, 2, 3, 4, 5],
 [5, 4, 3, 2, 1, 2, 3, 4, 5],
 [5, 4, 3, 2, 2, 2, 3, 4, 5],
 [5, 4, 3, 3, 3, 3, 3, 4, 5],
 [5, 4, 4, 4, 4, 4, 4, 4, 5],
 [5, 5, 5, 5, 5, 5, 5, 5, 5]]

Edit

The problem with current code is this:

sideAdd = [val] * n              
arr.insert(0, sideAdd)      
arr.append(sideAdd)  

You adding a reference to the same array ( sideAdd ) twice. So later when you add columns with:

arrx[i].insert(0, val)
arrx[i].append(val)

these two array are the same if they were added in an earlier loop. Adding to the first array also adds one to the second and adding to the second adds to the first. So you end up doing it twice. There are a couple ways to fix that, but the easiest is adding a copy the second time:

sideAdd = [val] * n              
arr.insert(0, sideAdd)   
arr.append(sideAdd[:]) # Make a copy — don't add the same reference

We can make use of numpy s broadcasting rules here:

>>> np.maximum(np.abs(np.arange(-2, 3)[:, None]), np.abs(np.arange(-2, 3))) + 1
array([[3, 3, 3, 3, 3],
       [3, 2, 2, 2, 3],
       [3, 2, 1, 2, 3],
       [3, 2, 2, 2, 3],
       [3, 3, 3, 3, 3]])

So we can render the cube with:

import numpy as np

def cube(n):
    ran = np.abs(np.arange(-n+1, n))
    cub = np.maximum(ran[:, None], ran) + 1
    return '\n'.join(' '.join(map(str, row)) for row in cub)

For example:

>>> print(cube(1))
1
>>> print(cube(2))
2 2 2
2 1 2
2 2 2
>>> print(cube(3))
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
>>> print(cube(4))
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
>>> print(cube(5))
5 5 5 5 5 5 5 5 5
5 4 4 4 4 4 4 4 5
5 4 3 3 3 3 3 4 5
5 4 3 2 2 2 3 4 5
5 4 3 2 1 2 3 4 5
5 4 3 2 2 2 3 4 5
5 4 3 3 3 3 3 4 5
5 4 4 4 4 4 4 4 5
5 5 5 5 5 5 5 5 5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM