0

I'm fairly new to programming and I'm trying to write a programm that will sort a list alphabetically. I would like to be able to change items from that list, but I have issues overwriting the original list with an updated one. This what I have right now:

def add_items():
  add_list = input("Please enter your additional items separated by space: ")
  list_to_add = add_list.split(" ")
  new_list = finished_list + list_to_add
  updated_list = sorted(new_list)
  finished_list = updated_list[:]

I already tried to use in this case:

finished_list = updated_list[:]

but I always get this: UnboundLocalError: local variable 'finished_list' referenced before assignment

I hope some of you can help me! Btw, if you have other tips on something just tell me, I'd love to improve ^^

Frank
  • 11
  • 2
  • In the line `new_list = finished_list + list_to_add` where does `finished_list` come from? You don't seem to define it anywhere. – timgeb Dec 09 '21 at 15:43
  • 2
    If finished_list is a global variable, you must declare it as such, otherwise a local variable by the same name is created – Michael Veksler Dec 09 '21 at 15:45
  • 1
    Does this answer your question? [Python 3: UnboundLocalError: local variable referenced before assignment](https://stackoverflow.com/questions/10851906/python-3-unboundlocalerror-local-variable-referenced-before-assignment) – Tomerikoo Dec 09 '21 at 15:46
  • You should always provide a [mre]. Anyway, by the looks of it, you have `finished_list` defined ***outside*** the function. The line `finished_list = ...` makes Python create another ***local*** variable with the same name. But when it get to the line `new_list = ...` that variable is not yet defined and hence you get the error... – Tomerikoo Dec 09 '21 at 15:48

1 Answers1

1

If you want to modify finished_list, you should pass it to your function as a parameter, and then call methods on it that will modify that original list, rather than assigning a different list to the same name:

def add_items(existing_items):
    add_list = input(
        "Please enter your additional items separated by space: "
    ).split()
    existing_items.extend(add_list)
    existing_items.sort()

and then call this with:

add_items(finished_list)

in order to add the items to finished_list.

The important distinction is in the way that the assignment operator works (I used existing_items as the parameter name above in order to make the following example easier to follow):

>>> finished_list = [1, 2, 3]
>>> existing_items = finished_list
>>> existing_items.extend([4, 5, 6])
>>> finished_list
[1, 2, 3, 4, 5, 6]

In the above example, I extend existing_items with more items, and because the name existing_items refers to finished_list, the new items show up in that list. What happens if instead I assign to existing_items?

>>> finished_list = [1, 2, 3]
>>> existing_items = finished_list
>>> existing_items = existing_items + [4, 5, 6]
>>> finished_list
[1, 2, 3]
>>> existing_items
[1, 2, 3, 4, 5, 6]

Because I did an assignment, I now have two different lists, and the original finished_list isn't affected. (Note that if I do things like existing_list.extend(...) at this point, it still won't affect finished_list, because existing_list ceased to reference finished_list as soon as I did existing_list = ....) You get the same exact behavior when you do this type of assignment inside a function, even if both of the variables are named finished_list, because the body of a function has its own namespace and can have its own variables that "shadow" variables of the same name in the calling namespace.

One more example, using slice assignment, which is what you were attempting to do in your function at one point:

>>> finished_list = [1, 2, 3]
>>> existing_items = finished_list
>>> existing_items[:] = existing_items + [4, 5, 6]
>>> finished_list
[1, 2, 3, 4, 5, 6]

Slice assignment is an operation that modifies the elements of a existing list rather than assigning a new name to another list. It looks very similar to a regular assignment, and in many cases might appear to behave identically, but it's very different, as the above examples show.

Samwise
  • 68,105
  • 3
  • 30
  • 44