我的Python变量发生了什么? old_pos
似乎与pos
:
代码:
pos = [7, 7]
direction = [1, 1]
old_pos = pos
print 'pos = '+str(pos)
print 'old_pos = '+str(old_pos)
pos[0] += direction[0]
pos[1] += direction[1]
print 'pos = '+str(pos)
print 'old_pos = '+str(old_pos)
输出:
pos = [7, 7]
old_pos = [7, 7]
pos = [8, 8]
old_pos = [8, 8]
但是,如果我将old_pos = pos
替换为old_pos = tuple(pos)
甚至old_pos = list(pos)
,我就不会遇到此问题:
pos = [7, 7]
old_pos = [7, 7]
pos = [8, 8]
old_pos = [7, 7]
答案 0 :(得分:12)
当您说old_pos = pos
时,您不是要创建pos
的副本,而只是创建对同一列表的另一个引用。如果您想要两个独立行为的列表,则需要制作副本,例如使用提及的list(pos)
函数或使用切片表示法pos[:]
。
答案 1 :(得分:7)
old_pos = pos
不会创建名称pos
所引用的对象的副本,而是为同一个对象创建名为old_pos
的第二个引用。对pos
所做的操作会影响old_pos
引用的同一对象。同样,名字“Steven”和“Mr. Rumbalski”都指的是我。如果你把史蒂文冲到脸上,Rumbalski先生将受伤,因为这两个名字指的是同一个物体 - 我。
以下是3种制作实际副本而非第二种引用的方法:
使用切片表示法
old_pos = pos[:]
使用列表构造函数
old_pos = list(pos)
使用复制模块
from copy import copy
old_pos = copy(pos)
请注意,这些副本都是浅色副本,在这种情况下很好。要了解浅拷贝和深拷贝之间的区别,请阅读documentation of the copy module。
答案 2 :(得分:3)
相关联
old_pos
似乎与pos
正确 - 这:
old_pos = pos
使old_pos
和pos
指向同一列表。它不会创建pos
的新副本。
答案 3 :(得分:3)
递归是关于原因的。您可以看到它们具有相同的内存地址:
>>> pos = [7, 7]
>>> old_pos = pos
>>> id(pos)
4299304472
>>> id(old_pos)
4299304472
这称为通过引用传递,而不是传递值。您还可以使用copy
模块来解决此问题。
>>> from copy import copy
>>> pos = [7, 7]
>>> old_pos = pos
>>> id(pos)
4299304472
>>> id(old_pos)
4299304472
>>> old_pos = copy(pos)
>>> id(old_pos)
4299349240
答案 4 :(得分:0)
除了上述注释之外,在多维数组的情况下还必须采取一些额外的步骤。例如,当您有一个二维数组var loginController = angular
.module('loginController', [])
.controller('LoginCtrl', LoginCtrl);
LoginCtrl.$inject = [
'$rootScope',
'$scope',
'$location',
'$timeout',
'ApiFactory',
'AUTH_EVENTS',
'AuthFactory'];
function LoginCtrl(
$rootScope,
$scope,
$location,
$timeout,
ApiFactory,
AUTH_EVENTS,
AuthFactory) {
/** Init LoginCtrl scope */
/** --------------------------------------------------------------------- */
var vs = $scope;
vs.login = login;
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
$rootScope.$on(AUTH_EVENTS.notAuthenticated, function (event, data) {
$rootScope.currentUser = null;
$scope.currentUser = null;
AuthFactory.logout();
$location.path('/login');
});
function login(credentials) {
console.log('credentials',credentials);
AuthFactory.login(credentials).then(function (user) {
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
$scope.setCurrentUser(user);
if (user.password_reset) {
$location.path('/password');
} else {
$location.path('/tickers');
}
}, function () {
// $scope.loginData.message = "Invalid Username/Password";
$rootScope.$broadcast(AUTH_EVENTS.loginFailed);
console.log('login failed!');
}
}
}
module.exports = loginController;
时,代码a = [[0,1,2],[3,4],[5,6,7,8]]
将不会创建一个独立的副本。但是,它将创建对二维列表中相同一维列表的引用的另一个引用。要解决此问题,必须对二维列表中的每个列表使用上述方法之一。例如,b = a
将创建列表的独立副本。