0
def findPair(students, Robert):
    #...
        if len(students) == 2:
            #do something
            return
        else:
            for friend in friendsOfRobert:
                print(students)
                leftStudents = removePairFromStudents(students, friend, Robert)
                if len(leftStudents) != 0:
                    findPair(leftStudents, leftStudents[0])
            return

I don't quite understand why students is modified as it loops inside for. It is not even global variable. The following is just to help you see the structure of the code.

  1. ... part : find friendsOfRobert from students
  2. for loop

    (1) suppose one friend and Robert was paired.

    (2) leftStudent: Remove the friend and Robert from students

    (3) Repeat findPair but this time without the friend and Robert. The next equivalent of Robert is randomly selected (leftStudents[0])

On the side note, I solved the issue by remembering the pair previously removed, and rebuilding the original students set each time (with code below) before it dives into the next loop.

if len(students) == 2:
    if len(justPaired) != 0:
        students.append(justPaired[0])
        students.append(justPaired[1])
    # do something
    return

edit : removed unnecessary example

  • 3
    You seem to be under the misunderstanding that functions get a copy of their arguments. This is not the case, they get the original object and can modify it (if it is mutable). – L3viathan May 08 '19 at 13:04
  • The local variable ``students`` is not changed. The object referred to by ``students`` is changed. Use a ``tuple`` instead of a ``list`` if you want an immutable sequence. – MisterMiyagi May 08 '19 at 13:19
  • @L3viathan Ohhh.. this makes it clear. Thank you for mentioning the mutable part. – PuffedRiceCrackers May 08 '19 at 13:20
  • Possible duplicate of [Correct Style for Python functions that mutate the argument](https://stackoverflow.com/questions/26027694/correct-style-for-python-functions-that-mutate-the-argument) – MisterMiyagi May 08 '19 at 13:21

1 Answers1

3

Functions do not get a copy of their argument. They get a copy of the reference to the argument. So, when you write

 f(x):
     x.append(3)
     x = [2,4,5]


 y = [1, 2]
 f(y)

the line x.append(3) affects the actual list that was passed, while the line x = [2, 4, 6] has no effect because it re-assigns the copy of the reference to the argument.

blue_note
  • 27,712
  • 9
  • 72
  • 90