1

I'm not sure why l would be modified by the find() function. I thought since I'm using a different variable in another function, l would not be modified by the function since it's not global.

I made sure it wasn't an error in the code by copy and pasting l = [2, 4, 6, 8, 10] before every print statement, and it returned the right outputs, meaning l is being changed by the function. I also removed the main function from the main and basically made it outright global, but it still gave the original bad results.

I'm not sure if this is an issue with my understanding of Python since I'm a beginner in it and I'm coming from Java.

Here's the code and results:

def find(list, user):
    while True:
        n = len(list)
        half = int(n/2)
        if n == 1:
            if user != list[0]:
                return "Bad"
            else:
                return "Good"
        elif user == list[half]:
            return "Good"
        elif user > list[half]:
            del list[0:half]
        elif user < list[half]:
            del list[half:n]
        print(list)

if __name__ == "__main__":
    l = [2, 4, 6, 8, 10]
    print(find(l, 5))  # should print Bad
    print(find(l, 10))  # should print Good
    print(find(l, -1))  # should print Bad
    print(find(l, 2))  # should print Good

but it returns with this

[2, 4]
[4]
Bad
Bad
Bad
Bad
Choop
  • 25
  • 5
  • 2
    `del ...` is modifying the original list since you are not passing in a copy of the list but rather a reference to the original list itself. Simplest fix is to pass in a copy of the list: `find(l[:], 5)` – sshashank124 Jan 03 '20 at 05:01
  • why do you use `print(list)` inside `find()` ? shouldn't be some `return text`. – furas Jan 03 '20 at 05:01
  • You should go for indices based approach and not use `del`. – GadaaDhaariGeek Jan 03 '20 at 05:05
  • The variable `list` is just a reference to the original list `l`. So when you modify the variable `list`, the original list also gets modified. Also please avoid using `list` as variable names as they are keywords in python. If you wanna modify the list just make a copy of it. – bumblebee Jan 03 '20 at 05:06

2 Answers2

0

Arguments in Python are passed by assignment. https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

In your case, that means that the list parameter of your find function is assigned the exact same list you pass in as the argument l. So, when you modify list (which is a very bad name since it shadows Python's list keyword), you also modify l, since no copy of the original was made.

You could use copy() to pass in a copy, but I think you would do well to reconsider the function as a whole, since it currently has many, many issues and you're likely to end up with a solution that won't suffer from having the original list passed in.

Grismar
  • 27,561
  • 4
  • 31
  • 54
0

You should read this question at first. why can a function modified some arguments while not others.

Let me rewrite your code for clarification.

def find(li, el):
    # li is a list, el is an integer
    # do something using li and el

if __name__ == "__main__":
    l = [1,2,3,4]
    e = 2
    find(l, e)    

The function find received two objects as parameters, one is li and the other is el. In main, we defined two objects, a list, we called it l, and an integer, we called it e. Then these two objects was passed to find. It should be clear that it is these two objects that passed to the function, not the name. Then your find function has access to this object, called l in main, while called li in find. So when you change li in find, l changed as well.

Hope that answers your question. And to fix this, check deepcopy.

Yaokun Xu
  • 64
  • 5