我想更改字典中的一个元素但是如果我将new_alien
放在循环之外,字典中的所有元素都会被更改。那是为什么?
#ALL aliens get changed when I put put the dictionary up here
new_alien = {'colour': 'green'}
aliens=[]
for alien_number in range(3):
#if i put new_alien here only one alien dictionary gets changed in the for loop (correct code)
#new_alien = {'colour': 'green'}
aliens.append(new_alien)
print(aliens)
for alien in aliens[0:1]:
if (alien['colour'] == 'green'):
alien['colour'] = 'yellow'
print(aliens[0:2])
如果new_alien
在循环之外,则输出:
[{'colour': 'green'}, {'colour': 'green'}, {'colour': 'green'}]
[{'colour': 'yellow'}, {'colour': 'yellow'}]
如果new_alien
在循环内,则输出:
[{'colour': 'green'}, {'colour': 'green'}, {'colour': 'green'}]
[{'colour': 'yellow'}, {'colour': 'green'}]
注意循环外的所有外星字典:颜色变为黄色。 任何解释将不胜感激。谢谢!
答案 0 :(得分:1)
Python Tutor是一款在线应用,可以向您展示会发生什么。您可以将代码粘贴到其中,并查看python解释器如何运行代码。
以下是纯文字的解释。
以下语句创建一个新的dict对象,而new_alien只是dict对象的引用。
new_alien = {'colour': 'green', 'points': 5, 'speed': 'slow'}
如果将this语句放在循环之外,则列表中的所有元素都引用相同的dict对象(或相同的内存空间),因为不为每个元素创建新的元素。
答案 1 :(得分:1)
如果您将new_alien
放在外面,则会一遍又一遍地追加相同的对象。您可以使用id()
打印出对象标识,以查看我的意思:
new_alien
:
for alien_number in range(3):
new_alien = {'colour': 'green', 'points': 5, 'speed': 'slow'}
print(id(new_alien))
aliens.append(new_alien)
输出不同的对象标识:
1577811864456
1577811864528
1577811864960
因此,您每次都会附加一个不同的对象。对new_alien
的不同引用,3个单独的对象。如果更改一个对象,则此处只更改一个对象。这是执行此操作的正确方法。
new_alien
:
new_alien = {'colour': 'green', 'points': 5, 'speed': 'slow'}
for alien_number in range(3):
print(id(new_alien))
aliens.append(new_alien)
你得到相同的身份:
2763267730312
2763267730312
2763267730312
这意味着您反复追加同一个对象。这意味着如果更改一个对象,则所有对象都将更改。这是因为它们都是对一个对象的引用。如果你想在将来修改它们,那就不行了。
答案 2 :(得分:1)
案例1:因此,当您append
new_alien = {'colour': 'green', 'points': 5, 'speed': 'slow'}
进入列表时,它会引用相同的object
内存。您可以通过id(Your_Object_Name)
检查内存引用。基本上它就像一个全局变量。
案例2:当你尝试append
从声明循环内部时,它会创建具有不同内存引用的不同对象。
答案 3 :(得分:1)
如果您将其放在外面,则会将相同的new_alien
对象附加到aliens
字典。如果您将其放入,则创建3个不同的new_alien
对象,然后将其附加到aliens
。
for loop (correct code)
new_alien = {'colour': 'green'}<-create a new dictionary {"c": "g"} and put it
under the name new_alien
aliens.append(new_alien) # add the new dictionary
虽然它们都添加了相同的变量new_alien
,但是在每轮循环期间绑定到new_alien
的内容是不同的。每当您有new_alien
的赋值语句(如new_alien = {'colour': 'green'}
)时,您(重新)绑定new_alien
到新创建的字典。因此,稍后在aliens
更改一个时,它不会影响其他人。
在另一种情况下:new_alien = {'colour': 'green'}
在之外的循环中,相同的对象引用将被插入字典中3次。当您将其中一个更改为"yellow"
时,您只需更改一个。 (实际上只有一个你可以改变它,即使它看起来有3个。)但是,当你打印它时,你也打印相同的字典存储 3次!这就是为什么它会给你相同的结果。
外卖:
在第一种情况下,new_alien
引用不同的字典对象,而循环在每一步执行。
在后一种情况下,new_alien
在循环之外,我们可以看到aliens[0]
,aliens[1]
和aliens[2]
都引用相同的字典对象。您更改其中一个,是的,只更改了一个对象。你换了两个;仍然,一个相同的字典被更改。你读了所有三个;你只是三次读同一本字典。
答案 4 :(得分:0)
python中的对象被视为内存中的地址。因此,对象的变量名称只是对存储该对象的计算机内存中的位置的引用。如果你运行这行代码:
<form action="primary-page.php" id="primary_page">
<input type="text" name="email" />
<input type="submit" value="Submit" />
</form>
1) data validate and stored in DB using ajax ( store-db.php )
2) email value post to primary-page.php using function frm_submit()
var form_validate = $("#primary_page");
form_validate.validate({
rules: {
email: {
required: true,
email: true
}
},
submitHandler: function () {
var param = form_validate.serialize();
var btn_submit = $("#submit");
$.ajax({
type: "POST",
url: '/store-db.php',
data: param,
cache: false,
dataType: "json",
success: function (response) {
frm_submit();
}
});
});
function frm_submit() {
form = document.getElementById('primary_page');
form.submit();
}
这会在内存中创建一个可由new_alien变量引用的对象。如果该行在循环之外,则它运行ONCE,而如果它在循环内部则运行多次。当这一行多次运行时,意味着在内存中创建了多个对象,但是当它运行一次时,只在内存中创建了一个对象,这就是为什么它们在外部声明时都会更新的原因;因为它们都引用了相同的内存位置。
答案 5 :(得分:0)
这称为浅拷贝,当您附加该项时,实际上是追加相同的对象,当您修改任何内容时,它将影响主对象:
解决方案:
你[co / sho]使用深度镜:
{display: block;}
输出:
from copy import deepcopy
#ALL aliens get changed when I put put the dictionary up here
new_alien = {'colour': 'green'}
aliens=[]
for alien_number in range(3):
#if i put new_alien here only one alien dictionary gets changed in the for loop (correct code)
#new_alien = {'colour': 'green'}
aliens.append(deepcopy(new_alien))
for alien in aliens[0:1]:
if (alien['colour'] == 'green'):
alien['colour'] = 'yellow'
print(aliens[0:2])
print(new_alien)