Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Reinitializing list
#1
Hi Guys,

I have written a function in which I have created a local list of pair values.
In the end, I append it to a global list.

The local list is declared inside for loop.
So when, the control goes inside loop second time or third time, it is not able to reinitialize the list.
Rather it still shows the data which I inserted 1st time.

The function code is attached below.
I am also sharing output.

def shortest(maxHeight, currentRow, currHeight, allPaths) :
   print("\n\nROW : "+str(currentRow))

   tempAllPaths = []

   if(currHeight == 0):
      for i in range (len(currentRow)) :
         if(currentRow[i]==1):
            weight = abs((i-in_pos))+1
            alive  = 1
            tempP = in_pos,currHeight
            pos = in_pos
            list_of_coordinates = []
            list_of_coordinates.append(tempP)
            inc = 1
            if(i<in_pos) :
               inc = -1
            for j in range (in_pos,i,inc):
               tempP = j-1,currHeight
               pos = j-1
               list_of_coordinates.append(tempP)
            print(i)
            print(list_of_coordinates)
            tempAllPaths.append((list_of_coordinates,weight,alive,pos))
      currHeight+=1

   elif(currHeight>0 and currHeight<maxHeight-1):
      print("Number of Paths : "+str(len(allPaths)))
      for a in range(len(allPaths)):
         if(allPaths[a][2] == 1):

            print("Path found alive")
            for i in range (len(currentRow)) :
               if(currentRow[i]==1):
                  tempPath = []
                  tempPath = allPaths[a][0]
                  print(i)

                  path = []
                  path = tempPath

                  print("Current : "+str(tempPath))
                  #print (tempPath)

                  curr_pos = allPaths[a][3]
                  weight = abs(i-curr_pos)+1
                  alive = 1
                  pos  = curr_pos

                  list_of_coordinates = []
                  tempP = curr_pos,currHeight
                  path.append(tempP)


                  inc = 1
                  if(i<curr_pos) :
                     inc = -1
                  for j in range (curr_pos,i,inc):
                     tempP = j-1,currHeight
                     path.append(tempP)
                     pos  = j-1


                  print("Final : "+str(path))
                  tempAllPaths.append((path,weight,alive,pos))
      
      currHeight+=1

   allPaths = tempAllPaths

   if(currHeight==maxHeight-1):
      return 1

   currentRow = amap[(maxHeight-currHeight)-1]
   shortest(maxHeight, currentRow, currHeight, allPaths)
Note : #debug-1 ("Current : "+str(tempPath)) in second run of for loop and #debug-2 (("Final : "+str(path))) in 1st run of for loop
gives same output.

Look at the output below :

Output:
ROW : [0, 0, 1, 0, 0, 0] 2 [(3, 0), (2, 0)] ROW : [1, 1, 0, 1, 0, 0] Number of Paths : 1 Path found alive 0 Current : [(3, 0), (2, 0)] Final : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1)] 1 Current : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1)] Final : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1), (2, 1), (1, 1)] 3 Current : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1), (2, 1), (1, 1)] Final : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1), (2, 1), (1, 1), (2, 1), (1, 1)]
Could some one help me fix this ?
Reply
#2
You should return the value and assign it. Put return tempAllPaths at the end of your function, and use allPaths = shortest(...) to call the function and assign the return value.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Hi @ichabod801,

Even this doesn't solve my issue.
But I guess, problem is not there where you have pointed.

Problem is inside for loop.

By "for loop", I mean line #29 .
Now assume that loop runs for 3 times.

So in its fun run(i.e. i=0), it executes the following statements :
Look at line #33: tempPath = allPaths[a][0]
Here it assigns, tempPath = [(3, 0), (2, 0)] (PS: Look at attached output #line: Current : [(3, 0), (2, 0)])
Then at line #40: path = tempPath; I assign same tempPath to a temporary variable called "path", so that no one can change the
original tempPath or allPaths[a][0] value.
Then at line #52 & #60: path.append(tempP); I appended some values in temporary variable "path".
Now the modified list looks like (Look at attached output #line: Final : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1)])
Note : I am not appending anything to my original variables tempPath or allPaths[a][0].

Now when the loop iterates for i=2, I get following issues :
At line #33: tempPath = allPaths[a][0]; These are the original list variable, which I have not modified anywhere.
But when I print "tempPath" at line #42 : print("Current : "+str(tempPath)),
Then I get output belonging to temporary variable "path" where I appended some values in previous run of for loop.
Look at the attached output #line : Current : [(3, 0), (2, 0), (2, 1), (1, 1), (0, 1)]
So, "Cuurent" value from current run of loop is same as "Final" value from previous run of loop.

Whereas the expected output should be, "Current" value should always be same and final value should only change.


Guys, please help me solve this issue. I have tried my best to explain the issue.
If you want I can forward my problem statement and program as well. You can run and test at your end.

Thanks in advance.
Reply
#4
(Jul-08-2019, 05:30 PM)Shivesh Wrote: Note : I am not appending anything to my original variables tempPath or allPaths[a][0].

Yes you are. Lists are mutable, so when you assign a variable name to one, you are assigning a pointer to the list. When you do path = tempPath, you are just reassigning that pointer, you are not making an independent copy of the list. To make a copy, you need to do path = tempPath[:] (a full slice of the list). Note that this makes a shallow copy of the list, so any sub-lists in the list will not get copied. But it looks like your lists are all tuples (which are immutable), so that shouldn't be a problem.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
Might be because, when I copy "allPaths[a][0]" to "tempPath",
Look at line #36 : tempPath = allPaths[a][0] :
And "allPaths[a][0]" also contains a list.

So could this be issue ?

If yes how can I fix this ? I need to copy entire list (0 to end) to tempPath.
Reply
#6
That's what I showed you in the last post. A full slice ([:]) returns a shallow copy of the whole list. So you would want tempPath = allPaths[a][0][:]. But you also need the fix I mentioned in my last post, or you will be changing tempPath without meaning to.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#7
Hey. Thank you very much. Yes this solved my issue.

I have one last issue.

When I am trying to return "tempAllPaths" at line #72 to main function.
In main function, I have written following line :
finalPath = shortest(maxHeight, currentRow, currHeight, allPaths)

When I try to look at the length of the list, I get error.
Line : print("Length : "+str(len(finalPath)))
Error: print("Length : "+str(len(finalPath)))
TypeError: object of type 'NoneType' has no len()


I also tried storing "tempAllPaths" to a global variable before return statement at line #72.
And I thought to use the global variable directly in main function, but when I print the length
of the list in main function, it gives zero.
The following line : print("Length : "+str(len(finalPath)))
gives output : Length : 0


Please help me with this. Thanks in advance.
Reply
#8
If finalPath is None, it is not reaching the return statement on line 72. I don't see another return statement, and the default return value is None.

Please don't use global variables, it's a real bad habit to get into. If you want to get tempAllPaths out of the function, return that instead of 1. It seems like you are returning 1 to indicate success. I would return tempAllPaths on success, and return an empty list for failure. The empty list can then be tested in a conditional, where it will resolve to False.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#9
Yes I have already modified the code.
Instead of returning 1, I am returning "tempAllPaths", but I am getting the errors which I reported in my previous message.

Anyways I have moved ahead from here now.
Actually, I needed to sort and print different paths.
So now I am not returning anything. Instead, I do these things there only.

Thanks for your help very much. I could solve the problem because of you.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020