0

The code below imports a linked list from LinkedQfile and creates a list object with some node objects. If I run this code the output from check_something() becomes CD . I thought linked_list in check_something() would become a local object inside the function and since I'm not assigning whatever I'm returning to anything it wouldn't change, that is I would expect the output ABCD. This is obviously not the case so I'm wondering if someone could explain to me what is going on here?

If linked_list was a global variable I would expect this outcome, my guess is that the return statements in each function returns some information to the object but I have no idea how and why! (I got the code from a lecture note and it works just like I want it to, I just want to know why!)

from LinkedQFile import LinkedQ

def check_something(linked_list):
    check_first_element(linked_list)
    check_second_element(linked_list)
    print(linked_list)

def check_first_element(linked_list):
    word = linked_list.dequeue()
    if word == "A":
        return

def check_second_element(linked_list):
    word = linked_list.dequeue()
    if word == "B":
        return

def main():
    list = LinkedQ()
    list.enqueue("A")
    list.enqueue("B")
    list.enqueue("C")
    list.enqueue("D")
    check_something(list)

main()

And if needed, the LinkedQFile:

class Node:

    def __init__(self, x, next= None):
        self._data = x
        self._next = next 

    def getNext(self):
        return self._next  

    def setNext(self, next):
        self._next = next 

    def getValue(self):
        return self._data

    def setValue(self, data):
        self._data = data  



class LinkedQ:

    def __init__(self):
        self._first = None
        self._last = None 
        self._length = 0  

    def __str__(self): 
        s = ""
        p = self._first
        while p != None:
            s = s + str(p.getValue())
            p = p.getNext()
        return s


    def enqueue(self, kort):
        ny = Node(kort)
        if self._first == None: 
            self._first = ny 

        else:  
            self._last = self._first 
            while self._last.getNext():   
                self._last = self._last.getNext()

            self._last.setNext(ny)    
        self._length += 1    

    def dequeue(self): 
        data = self._first.getValue()
        self._first = self._first.getNext()
        self._length = self._length - 1
        return data 
Nekroz
  • 169
  • 1
  • 1
  • 11
  • 1
    Well your functions *do* "dequeue" (i.e. remove) an item from the list. So of course the list will be modified by calling them. You need to [read about how Python passes arguments to functions and how it works](http://stackoverflow.com/a/986145/440558). – Some programmer dude Dec 17 '15 at 12:45
  • 2
    http://stackoverflow.com/questions/17686596/function-changes-list-values-and-not-variable-values-in-python – Mel Dec 17 '15 at 12:50
  • Thanks a lot, I learned a lot from both your links! – Nekroz Dec 18 '15 at 08:30

1 Answers1

1

You're right about linked_list being a local variable, but just because a variable is local doesn't mean it can't reference something that isn't. In order for it to do what you expected, it would need to copy your entire linked list every time you pass it to a function, which wouldn't make sense.

Here's a simple example that illustrates the idea of a shared object. In this example, an empty list is created and assigned to a. Then a is assigned to b. This does not copy the list. Instead, there is a single list, referenced by both a and b. When it is modified, through either a or b, both a and b reflect the change:

>>> a = []
>>> b = a
>>> a.append("x")
>>> a
['x']
>>> b
['x']
>>>

The same thing is happening with your class objects. In fact, your linked lists wouldn't work at all if it didn't.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41