Reputation: 151
I have two functions foo()
and bar()
, which use two lists l1
and l2
.
foo()
makes a function call to bar()
with l1
and l2
as arguments.
bar()
mutates the lists l1
and l2
. foo()
needs to know of these changes to the lists hence the lists are returned by bar()
.
Instead of this passing of lists as arguments and returning them is there a better way to update the lists in foo()
?
def bar(l1, l2):
value=10
l1.append(value)
l2.append(value)
return l1,l2
def foo() :
list1=[]
list2=[]
list1, list2 = bar(list1,list2)
def main():
foo()
if __name__ == '__main__':
main()
Upvotes: 0
Views: 81
Reputation: 113975
I have modified your code as follows:
def func2(list1, list2):
value=10
list1.append(value)
list2.append(value)
def func1():
list1=[]
list2=[]
func2(list1,list2)
Notice that func2
does not return anything. This is not a problem, since it uses list.append
, which modifies the list IN-PLACE. This means that when func2
finishes execution, the changes to list1
and list2
still persist.
On the other hand, if you were to have done list1 = list1 + [5]
, that is a change that would not persist after func2
finished execution.
Thus, with the above code, func1
will be aware of changes made to the two lists by func2
even after the execution of func2
is complete.
In [13]: def func2(list1, list2):
....: value = 'a'
....: list1.append(value)
....: list2.append(value)
....:
In [14]: def func1():
....: myList = []
....: myOtherList = [1]
....: print myList, myOtherList
....: func2(myList, myOtherList)
....: print myList, myOtherList
....:
In [15]: func1()
[] [1]
['a'] [1, 'a']
In [16]: def otherfunc2(list1, list2):
....: value = 'a'
....: list1 = list1 + [value]
....: list2 = list2 + [value]
....:
In [17]: def func1():
....: myList = []
....: myOtherList = [1]
....: print myList, myOtherList
....: otherfunc2(myList, myOtherList)
....: print myList, myOtherList
....:
In [18]: func1()
[] [1]
[] [1]
Upvotes: -1
Reputation: 44364
Looking at your modified question, there is no need to return the lists, they are passed by reference anyway and will be modified:
def func2 (list1,list2):
value=10
list1.append(value)
list2.append(value)
def func1() :
list1=[]
list2=[]
func2(list1,list2)
print "list1:",list1,"list2:",list2
func2(list1,list2)
print "list1:",list1,"list2:",list2
func2(list1,list2)
print "list1:",list1,"list2:",list2
def main():
func1()
if __name__ == '__main__':
main()
Gives:
list1: [10] list2: [10]
list1: [10, 10] list2: [10, 10]
list1: [10, 10, 10] list2: [10, 10, 10]
Upvotes: 0
Reputation: 365757
From your description and your comments, it sounds like your real func2
looks like this:
def func2(list1, list2):
value = 'a'
list1.append(value)
list2.append(value)
return list1,list2
This mutates list1
and list2
in place, so whoever calls it is going to see the changes. And it also returns list
and list2
, so whoever calls it can use the results that way.
So, in func1:
def func1() :
list1=[]
list2=[]
func2(list1, list2)
print(list1, list2)
You're going to see that both values are ['a']
.
And if you do this:
(list1,list2) = func2([],[])
print(list1, list2)
You're also going to see that both values are ['a']
.
You don't actually need—or usually want—to both mutate the values and return them. Just do one or the other:
def mutating_func2(list1, list2):
value = 'a'
list1.append(value)
list2.append(value)
def non_mutating_func2(list1, list2):
value = 'a'
return list1+[value], list2+[value]
You can use mutating_func2
in code like func1
, which just passes two lists and expects to have them modified. You can use non_mutating_func2
in code like your top-level code, which passes two lists and expects to get back two new lists. Both are perfectly reasonable things to do.
Upvotes: 0
Reputation: 113988
As others have mentioned since you are modifying the contents - in-place - of the lists passed in you do not need to return anything
def func2 (list1,list2):
value=10
list1.append(value)
list2.append(value)
listA = [1,2,3]
listB = [7,8,9]
func2(listA,listB)
print listA
print listB
Upvotes: 2