3

For example, the dictionary below updates for changes in the list but not for the int.

What is the name of the property of the data type that tells me if it will act like the int or like the list in this example?

How do I set this property when building classes?

Is there a way to make the "i" variable in my example behave like the "l" variable?

i = 1
l = [1]

d = {'i':i,'l':l}
i = 0
l[0] = 0
print(d) # {'i': 1, 'l': [0]}
Charles Fox
  • 261
  • 2
  • 10
  • 4
    Some people are going to post answers saying "these types act like pointers, and others don't". Don't listen to them, they're wrong. All types act like pointers in python. – Aran-Fey Jun 06 '19 at 22:59
  • 3
    I'm too tired to write an actual answer, but TL;DR: That property you're looking for is "mutability". Lists are mutable, ints are not. Also, there's a crucial difference between `i = 0` and `l[0] = 0`. The former assigns a new value to the variable `i`. The latter modifies the list object stored in the variable `l`. They're two entirely different operations. – Aran-Fey Jun 06 '19 at 23:04
  • 2
    Related question: [Immutable vs Mutable types](https://stackoverflow.com/q/8056130/7131499) – FJSevilla Jun 06 '19 at 23:07
  • 1
    Related question: [How do I pass a variable by reference?](https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) – jwodder Jun 06 '19 at 23:07
  • 2
    The semantics of variables in python *do not change based on the type*. Immutable types *simply lack mutator methods*, but they work exactly the same as mutable types. Just read the following: https://nedbatchelder.com/text/names.html Long story short, **you never changed the int** but you **did change the list**. *Assignment* **never** mutates. – juanpa.arrivillaga Jun 06 '19 at 23:15

1 Answers1

2

Python passes things around by assignment, so basically Python always passes a reference to the object, but the reference is passed by value.

An example where the value of the reference is not changed:

def foo(list_):
    list_.append(0)

l = [3, 2, 1]
foo(l)
# l = [3, 2, 1, 0]

Now one where it is changed:

def foo(list_):
    list_ = [1, 2, 3]

l = [3, 2, 1]
foo(l)
# l = [1, 2, 3]

You could also get a copy of the list:

def foo(list_):
    list_copy = list_.copy()
    list_copy.append(0)

l = [3, 2, 1]
foo(l)
# l = [3, 2, 1]

In your example you changed the value of the reference of the i variable inside the dict d, but not of the list l, you used the reference and changed an item inside the list. This happened because lists are mutable, Python integers are not, you made two different operations. You won't be able to change what is inside the dict d using the variable i after the assignment, you would need to do d['i'] = 0 for that.

Charles Fox
  • 261
  • 2
  • 10
Vitor Falcão
  • 1,007
  • 1
  • 7
  • 18