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

Mar*_*907 3 c++ python recursion subset

我正在 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]]
Run Code Online (Sandbox Code Playgroud)

我有被接受的 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)
Run Code Online (Sandbox Code Playgroud)

输出现在是:[[],[],[],[],[],[],[],[]]

似乎是 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);
}
};
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 10

问题在这里:

solutions.append(path)
Run Code Online (Sandbox Code Playgroud)

在 C++ 中,vector::push_back复制path(内部)。但在 Python 中,一切都是参考。因此,您将自己构建solutions为对相同 的许多引用的列表path,最终会减少到零。

你想要一个副本:

solutions.append(list(path))
Run Code Online (Sandbox Code Playgroud)

或者:

solutions.append(path[:])
Run Code Online (Sandbox Code Playgroud)