1

I have a list with integers and strings l = [1, 2, 'a', 'b'] and want to write a function that takes the list and manipulates it in a way that it just contains integers afterwards. The function output looks like what I want to have, but it doesn't change the "original" list.

def filter_list(l):
  temp =[]
  for item in l:
      if type(item) == int:
          temp.append(item)
  l = temp
  return l
Function output: [1, 2]
Variable explorer: [1,2,'a','b']

In contrast, the function

def manipulate(l):
    l.append("a")
    return l
Function output: [1, 2, 'a', 'b', 'a']
Variable explorer: [1, 2, 'a', 'b', 'a']

changes the "original" list.

  1. What's the difference between theses 2 function, i.e. why does the
    second one manipulate my "original" list, but the first one doesn't?
  2. How do I have to adjust function 1 in order to get the desired output?

Thanks!

b_sharp
  • 21
  • 2
  • Why dont' you set `l` as `global` ? `global l` – Pedro Lobito Mar 02 '20 at 15:32
  • 2
    Think about what `l` is in the first function. It's the parameter, not the global, and reassigning a parameter has no effect outside of the function. – Carcigenicate Mar 02 '20 at 15:33
  • And in `manipulate()` you are mutating the object passed to it. `append` mutates list in place. So, `l` is changed. Don't change 1st function just do `l=filter_list(l)` and replace these `l = temp return l` with `return temp`. – Ch3steR Mar 02 '20 at 15:35
  • Thanks! I tried both `l = filter_list(l)` and flagging `l`as `global` inside my function, and it works. – b_sharp Mar 02 '20 at 16:09

1 Answers1

0

In python, all objects are passed to functions by reference, meaning you can change the object passed to your function. That's why when you call the append method in your second example the list changes.

However, if you assign a different object to the argument that was passed (l = temp), then you change the reference itself and therefore can not make changes to the original object from the outer scope. That's not a problem in your case, though, because you return the new reference, as you should in this case.

chuck
  • 1,420
  • 4
  • 19
  • So my thinking that with `l = temp` I replace the current value of `l` with `temp` is wrong? It's more that the reference from `l` to the original object gets replaced by a reference from `l`to `temp`, and once the function is exited, this reference gets deleted? – b_sharp Mar 02 '20 at 15:54
  • Almost - `l` doesn't become a reference from `l` to `temp`, it becomes another reference to what `temp` is referencing. But yes, I think you basically got it. – chuck Mar 02 '20 at 16:00
  • Thanks! The reference thing changes a lot in terms of how I thought variables work. Will have to dig deeper into this topic for sure though. – b_sharp Mar 02 '20 at 16:06
  • Yes, it's definitly useful to understand. Note that this is different between languages. Check out C pointers for a deeper understanding of this. – chuck Mar 02 '20 at 16:08