Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my function overwrite a list passed as a parameter?

I have created a function that takes a list as a parameter. It shuffles the list, replaces the first element and returns the new list.

import random
firstList=["a","b","c","d","e","f","g","h","i"]

def substitution(importedList):
    random.shuffle(importedList)
    importedList[0]="WORD"
    return importedList

The shuffle has no impact on my question. However, I was surprised to see that the returned importedList overwrites the original firstList.

>>> firstList
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

>>> substitution(firstList)
['WORD', 'a', 'b', 'd', 'i', 'c', 'g', 'e', 'h']

>>> firstList
['WORD', 'a', 'b', 'd', 'i', 'c', 'g', 'e', 'h']

I have found a workaround by copying the list within the function, but it seems inefficient.

import random
firstList=["a","b","c","d","e","f","g","h","i"]
string="a"

def substitutionandcopy(importedList):
    copiedList=importedList[:]
    random.shuffle(copiedList)
    copiedList[0]="WORD"
    return copiedList

My question is why does the function replace the firstList? This would not happen if it were a string for example.

string="a"

def substituteString(foo):
    foo='b'
    return foo

>>> string
'a'

>>> substituteString(string)
'b'

>>> string
'a'
like image 679
DaveOB Avatar asked Feb 16 '16 11:02

DaveOB


People also ask

How to pass a function as a parameter to another function?

In C++ 11, there is a std::function<> template class that allows to pass functions as objects. An object of std::function<> can be created as follows. Below is the program to illustrate the passing of a function object as a parameter to another function:

Why do my lists get modified when I use a function?

Your lists get modified because lists are mutable objects that are capable of being modified, and you modify them Objects are not copied when you pass them to a function. Any modification you make to the object is visible outside the function.

How to pass a function as an argument in C/C++?

Passing a function as an argument is a useful concept in C/C++. This concept has already been used while passing a custom comparator function as an argument in std::sort() to sort a sequence of objects as per the need. In this article, we will discuss different ways to design functions that accept another function as an argument.


Video Answer


1 Answers

Strings, Ints, Tuples are immutable python types, so when you perform operations that change one of these types the new corresponding object is effectively created in memory each time. (Or you get an error if trying to change those in-place.)

Lists and dictionaries are mutable python types, so when you perform operations that change one of these types, the object stays the same, but it's parts (i.e., list elements) get changed.

So when you want to change a list, but want to leave the original intact you have to copy it yourself. Important thing, that there're two types of copying - shallow copy and deep copy.

Shallow copy can be done like so:

list_b = list_a[:] #using slice syntax

#or

list_b = list(list_a) #instantiating a new list from iterating over the old one

#or

import copy
list_b = copy.copy(list_a) #using copy module

Deep copy is done in the following way:

import copy
list_b = copy.deepcopy(list_a)

The difference between deep copy and shallow copy is...

When doing shallow copy, if mutable object contains other mutable objects, only the top one is copied. I.e. if a list contains other list, if top list is copied and then the inner list is changed in the copy, effectively the inner list will be changed both in the copy and in the original, because it's the same object in memory that is referenced in two different lists. Basicly shallow copy creates a new object with the same references stored in original object.

When doing deep copy, if mutable object contains other mutable objects, then inner mutable objects are copied too. I.e. as in previous example, if you change inner list in the copy, it changes only in the copy and the original is not affected. So deep copy copies everything, creates new structure in memory for everything in the object being copied, and not just references.

like image 132
Nikita Avatar answered Sep 20 '22 18:09

Nikita