shadow = [{
"name": "admin",
"password": "admin",
"age": "18",
},
{
"name": "xys",
"password": "123132",
"age": "18",
}
]
arr1 = list(filter(lambda x:x["name"] == "xys", shadow))
arr1[0].update({
"name": "yourself"
})
print(arr1) # 输出 [{'name': 'yourself', 'password': '123132', 'age': '18'}]
print(shadow[1]) #输出 {'name': 'yourself', 'password': '123132', 'age': '18'}
问:为什么在arr上修改值会影响源数值
在Python中,列表(list)是可变的数据类型,这意味着对列表的修改会直接在原始列表上生效,而不是创建一个新的副本。因此,当你通过arr1 = list(filter(lambda x:x["name"] == "xys", shadow))
将shadow
中满足条件的字典(dictionary)引用赋值给arr1
时,arr1
实际上是指向原始列表shadow
中符合条件的字典的引用,而不是创建了一个新的独立的列表。
所以,当你修改arr1
中的字典时,也就是arr1[0].update({...})
,原始列表shadow
中对应的字典也会被修改,因为它们实际上是同一个对象。这就是为什么在arr
上对值进行修改会影响源数值的原因。
如果你希望对arr1
进行修改而不影响原始列表shadow
,可以使用copy()
方法创建一个副本,或者使用切片(Slice)创建一个新的列表,这样就可以在副本或新列表上进行修改,而不影响原始列表。
例如,可以这样修改代码:
python
import copy
shadow = [{
"name": "admin",
"password": "admin",
"age": "18",
},
{
"name": "xys",
"password": "123132",
"age": "18",
}
]
arr1 = copy.deepcopy(list(filter(lambda x: x["name"] == "xys", shadow)))
arr1[0].update({"name": "yourself"})
print(arr1) # 输出 [{'name': 'yourself', 'password': '123132', 'age': '18'}]
print(shadow[1]) # 输出 {'name': 'xys', 'password': '123132', 'age': '18'}
这样做可以确保对arr1
的修改不会影响原始列表shadow
中的值。
这是因为在 Python 中,列表(list)是可变对象(mutable object)。当你将一个列表赋值给另一个变量时,并不是创建了一个新的列表副本,而是创建了另一个引用(reference)指向同一块内存地址。因此,当你修改其中一个变量时,另一个变量也会受到影响。
例如:
arr = [1, 2, 3]
new_arr = arr
new_arr[0] = 4
print(arr) # Output: [4, 2, 3]
这里,new_arr 并不是 arr 的副本,而是指向同一个列表对象的另一个引用。当你修改 new_arr[0] 的值时,arr 也会发生变化。
如果你想创建一个列表的副本而不影响原始列表,可以使用以下方式:
使用切片操作 new_arr = arr[:]
使用 list() 函数 new_arr = list(arr)
使用 copy 模块 import copy; new_arr = copy.copy(arr)
这样就可以创建一个新的列表对象,不会影响原始列表。
例如:
arr = [1, 2, 3]
new_arr = arr[:]
new_arr[0] = 4
print(arr) # Output: [1, 2, 3]
print(new_arr) # Output: [4, 2, 3]
这里 new_arr = arr[:] 创建了一个新的列表对象,修改 new_arr 不会影响 arr。
可以了解下深浅拷贝