0

I know Python is working by " pass by reference ". However when I was trapped in a bug with hours I felt like I still didn't understand how things happened. Below is my code, which is using deep first search to implement listing all subset of a set.

def subset_of_unique_dfs(mylist):
"""
:param list: a list of char first assuming the element in the list is unique
:return: list of subset of the input list
we could treated as tree, with ith level represent the ith element is selected or not (binary tree)
when we reach the leafnode of the tree, append the result
so we need to track the level of the tree where we currently at
"""
result_list = []
def helper(thelist, level, curList,result):
    print("at level ",level, "curResult is ",curList)
    if level == len(thelist):
        print type(curList)
        result.append(curList)
        return
    curList.append(thelist[level])
    helper(thelist,level + 1,curList,result)
    curList.pop()
    helper(thelist,level + 1,curList,result)

helper(mylist, 0, [],result_list)
return result_list

print subset_of_unique_dfs(['a','b','c'])
"""
[[], [], [], [], [], [], [], []]
"""

I have been struggling for a while while an empty list was returned. Then I tried to change "result.append(curList)" to "result.append(list(curList))", correct result is returned. May I ask what happened by applying list(curList)? I used to take result.append(curList) as appending the object that binding with curList to result. For example, the below test case actually showed no difference between append(listA) and append(list(listA))

tmp1 = [[1,2],[2,3]]
tmp1_1 = [[1,2],[2,3]]
tmp2 = [3,4]
tmp1.append(tmp2)
tmp1_1.append(list(tmp2))
print tmp1
print tmp1_1
"""
[[1, 2], [2, 3], [3, 4]]
[[1, 2], [2, 3], [3, 4]]
"""
evehsu
  • 39
  • 4
  • Python is not 'pass by reference' (nor 'pass by value'), and you will not understand it as long as you think it is. 'Pass by object' is perhaps the best description. – Terry Jan Reedy Dec 10 '17 at 01:37
  • I found a similar question (https://stackoverflow.com/questions/45335809/python-pass-by-reference-and-slice-assignment) However still a little struggle to understand that "So you build up your solutions as a list of many references to the same path, which eventually gets reduced to nothing". I actually thought it was the same reference for different objects(path) as it has been modified through append and pop...and i'm even more confused by "reduced to nothing". (https://stackoverflow.com/users/2069064/barry) – evehsu Dec 10 '17 at 01:42
  • @TerryJanReedy: "nor 'pass by value'" The semantics of passing and assigning in Python are identical to that in Java, and Java is universally called pass-by-value on this site. – newacct Dec 16 '17 at 20:46
  • At https://en.wikipedia.org/wiki/Evaluation_strategy, the call-by-value, call-by-reference, and call-by-sharing sections explain how 'pass-by-value' is misleading for Java objects. Python is call-by-sharing (or call-by-object or object-sharing). Java has unboxed values, which Python does not, and I presume that those Java values *are* passed by value as commonly understood, in the strict, non-reference sense. Fortran, C, and the traditional value/reference dichotomy, predates Java by decades. The Java use of 'value' to mean reference is misleading to most Python beginners. – Terry Jan Reedy Dec 17 '17 at 00:52
  • @evehsu They are actually quite different. Assign `tmp2[0] = 333` and print `tmp1` and `print tmp1_1` again. – Stop harming Monica Jan 10 '18 at 15:43

1 Answers1

2

The output of list(tmp2) equals that of tmp2 in your test case, it would work like that:

tmp1 = [[1,2],[2,3]]
tmp1_1 = [[1,2],[2,3]]
tmp2 = [3,4]
tmp1.append(tmp2)
tmp1_1.append([tmp2])
print tmp1
print tmp1_1
"""
[[1, 2], [2, 3], [3, 4]]
[[1, 2], [2, 3], [[3, 4]]]
"""
Tim von Känel
  • 301
  • 2
  • 12
  • Thanks for your answer. Would you help me more to clarify that tmp1.append(tmp2) actually append the object that binding to the name of tmp2 rather than appending the reference of tmp2, but why when back to my function, result.append(curList) would only append the reference? – evehsu Dec 10 '17 at 02:37