Python递归是按引用还是按值传递?

5
我正在Leetcode上解决这个问题:
Given a set of distinct integers, nums, return all possible subsets.
input =[1,2,3]
output =[[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]

我有一份C++的解决方案,已经被接受了,然后我编写了完全相同的Python解决方案。

class Solution(object):    
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        solutions = []
        self._get_subset(nums, 0, [], solutions)

        return solutions

    @staticmethod
    def _get_subset(nums, curr, path, solutions):
        if curr>= len(nums):
            solutions.append(path)
            return

        path.append(nums[curr])
        Solution._get_subset(nums, curr+1, path, solutions)

        path.pop()
        Solution._get_subset(nums, curr+1, path, solutions)

现在的输出为: [[],[],[],[],[],[],[],[]]
似乎是 Python 的传引用 / 传值导致了问题,但我无法弄清楚原因。相同的 C ++ 代码可正常工作:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
    vector<vector<int>> solutions;
    vector<int> path;

    _get_path(nums, 0, path, solutions);
    return solutions;
}

void _get_path(vector<int>& nums, 
               int curr,
               vector<int>& path,
               vector< vector<int> > &solutions)
{
    if(curr >= nums.size()){
        solutions.push_back(path);
        return; 
    }
    path.push_back(nums[curr]);
    _get_path(nums, curr+1, path, solutions);

    path.pop_back();
    _get_path(nums, curr+1, path, solutions);
}
};

1
“path”是通过引用传递的,因此您始终只操作同一实例。传递“ path[:]”以传递可修改的副本。 - njzk2
1个回答

12

问题在这里:

solutions.append(path)
在C++中,vector::push_back会在内部复制path。但是在Python中,所有东西都是引用。因此,您将solutions构建为对同一path的许多引用的列表,最终会被减少到零。
您需要一个副本:
solutions.append(list(path))
或:
solutions.append(path[:])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接