简体   繁体   中英

Why do python lists persist outside function scope while integers don't?

Python works so that I can update a list in place every time a function runs:

list_obj = list()
def increase_list_obj(list_obj, n):
    list_obj.append(n)

print(list_obj)
for n in range(3):
    increase_list_obj(list_obj, n)
    print(list_obj)

OUTPUT:

[]
[0]
[0, 1]
[0, 1, 2]

Based on how the list persists I would expect that I can also update an int in place every time a function runs:

int_obj = 0
def increase_int_obj(int_obj):
    int_obj += 1

print(int_obj)
for n in range(3):
    increase_int_obj(int_obj)
    print(int_obj)

OUTPUT:
0
0
0
0

EXPECTED:
0
1
2
3

Why does the int update not work the same way as the list update? How are the persistence and scoping rules different for these two objects?

(I am NOT trying to suggest that the two should behave the same, I am curious about why they don't)

To preempt answers about how to update an int : I realize you can update the int value by just returning it from the function:

int_obj = 0
def increase_int_obj_v2(int_obj):
    int_obj += 1
    return int_obj

print(int_obj)
for n in range(3):
    int_obj = increase_int_obj_v2(int_obj)
    print(int_obj)

OUTPUT:
0
1
2
3

Thank you!

To better understand, you need to know some concepts

int is immutable and list is mutable

List of Mutable and Immutable objects Objects of built-in type that are mutable are:

  • Lists
  • Sets
  • Dictionaries
  • User-Defined Classes

Objects of built-in type that are immutable are:

  • Numbers (Integer, Rational, Float, Decimal, Complex & Booleans)
  • Strings
  • Tuples
  • Frozen Sets
  • User-Defined Classes (It purely depends upon the user to define the characteristics)

what does it mean?

for more info about immutable and mutable read this

some objects passing to function by reference and some passing by value ( more )

Variables are local if there is an assignment within a function, otherwise they are global:

 i += 1

is an assignment ( i = i + 1 )! Therefore i is a local variable within the function.

list_obj.append(n)

is a mutation ! Therefore list_obj is looked up in the enclosing namespace which is the global one.

Side note: += can be a mutation for mutable types: list_obj += [n] would be a mutation as well.

Objects in Python can be modified from any scope. The thing about integers is they are immutable objects so whenever they are modified they make a new copy of themselves which will only exist within the scope it is created.

Lists on the other hand are like all other Python objects and will be modified in place allowing for changes to be made regardless of the current scope.

Here is an example using a custom object.

class HoldInt:
  def __init__(self, integer):
    self.integer = integer

int_obj = HoldInt(0)

def modify_int():
  int_obj.integer += 1

print(int_obj.integer)
modify_int()
print(int_obj.integer)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM