2

I want to pass a new instance of 2D array to a function. I have tried the common answers like using the list(old) or doing a old[:]. Still I am getting the same reference.
The only reason I can think of is using nested methods which I don't understand well due to my C background. If anyone can explain why the code is behaving in this way it would really help me understand the magic of python.

Code for reproduction (Edited to make it minimal and more descriptive)-

from pprint import pprint as pp
class Solution:
    def solveNQueens(self, a):
        b1 = [['.' for i in range(a)] for j in range(a)]    #base list with queens positions and empty positions
        b2 = list(b1)   #to make a seperate list with na positions marked as x

        def fillRows(i, j, b, p):
            b[i][j] = 'Q' #add queens position
            for x in range(i + 1, a):
                p[x][j] = 'x'       #cross straight entries
            return b, p

        def queenFill(i, b, p):
            for j, e in enumerate(p[i]):
                if e == '.':
                    pp(p)
                    bx = []
                    bx.extend(b)    # trying to create new array duplicate that original array is unaffected by fillRows
                                    # but as seen from print p is getting changed still, it should be same for every print call
                    px = []
                    px.extend(p)
                    bt, pt = fillRows(i, j, list(bx), list(px)) #trying to create new array duplicate using another method

        queenFill(0, b1[:], b2[:]) #trying to create new array duplicate using another method 

s = Solution()
s.solveNQueens(4)

The output I am getting is -

[['.', '.', '.', '.'],
 ['.', '.', '.', '.'],
 ['.', '.', '.', '.'],
 ['.', '.', '.', '.']]
[['Q', '.', '.', '.'],
 ['x', '.', '.', '.'],
 ['x', '.', '.', '.'],
 ['x', '.', '.', '.']]
[['Q', 'Q', '.', '.'],
 ['x', 'x', '.', '.'],
 ['x', 'x', '.', '.'],
 ['x', 'x', '.', '.']]
[['Q', 'Q', 'Q', '.'],
 ['x', 'x', 'x', '.'],
 ['x', 'x', 'x', '.'],
 ['x', 'x', 'x', '.']]

While it should be like this as I am not changing the varible I am printing anywhere, I am creating duplicate of that -

   [['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.']],
[['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.']]
[['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.']]
[['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.'],
     ['.', '.', '.', '.']]
Naman Jain
  • 63
  • 1
  • 9
  • Add the following to run - s = Solution() s.solveNQueens(4) – Naman Jain Feb 24 '19 at 15:48
  • Nested methods are rarely used in python too, there's rarely a reason to need them other than, say, decorators – roganjosh Feb 24 '19 at 15:49
  • 2
    You seem to have posted more code than what would be reasonable for your issue. Please read [ask] and how to make a [mcve], providing a MCVE helps users answer your question and future users relate to your issue. To display _Not able to do pass by value in python inside a nested function_ can be displayed in 5-10 lines. Your code gives your output,no error. I am not sure how you come from "input" to your expected output - maybe you can descibe it better? – Patrick Artner Feb 24 '19 at 15:58
  • 1
    You don't explain what your code is trying to do and on top of that it's obfuscated. – Reti43 Feb 24 '19 at 16:11
  • 2
    @NamanJain, while you have posted the code, and mentioned the expected output and actual output, it doesn't help at all, for your problem. Except for the most trivial of code, you cannot expect anyone to understand what this code is expected to do, simply based on the expected and actual output. Also, regarding your observation about argument passing not behaving as expected, you haven't mentioned which function and which argument and what value you are you referring to. – fountainhead Feb 24 '19 at 16:17
  • @PatrickArtner my bad, edited the question, hopefully it more understandable now – Naman Jain Feb 24 '19 at 16:30
  • @Reti43 Edited the code – Naman Jain Feb 24 '19 at 16:31

1 Answers1

1

b1 is a list that contains inner lists. Copying it, either using list(b1) or b1[:] copies the outer list, but not the inner lists.

If you want to copy the inner lists as well, try using copy.deepcopy.

user200783
  • 13,722
  • 12
  • 69
  • 135