这使我变得非常疯狂,因此任何帮助将不胜感激。我有一个程序在其中遍历函数中的列表。这是问题的玩具模型:
masterList = ["person","woman","man","camera","television"]
workingList = masterList
def removeItem (workingList):
item = workingList.pop(2)
print("Test 1:",workingList)
removeItem(workingList)
print("Test 2:", workingList)
print("Test 3:", masterList)
如预期的那样,“测试1”将打印出删除了项目的列表。
但是,“测试2”也会打印出删除了项目的列表。我没想到,但是没关系。这不是真正的问题,但是我敢肯定,在这里我对可变范围和可变阴影不了解。
没有真正的问题是“测试3”,如您所见,它正在打印出母版列表,该列表甚至不应该被removeItem
功能或其中的pop
函数。但是,它也正在打印出已删除项目的列表。
这怎么可能发生,我该如何预防?
非常感谢!
干杯, 阿里
答案 0 :(得分:3)
Python列表是可变对象。
m = list([1, 2, 3])
n = m
a = 5
b = a
id(a) == id(b)
# id() return "identity" of the object.
# True, Both a and b are references to the same object.
id(m) == id(n)
# True, Both m and n are references to the same object.
b = b + 2
id(a) == id(b)
# False, a new object on separate location is created, which b will point.
n.pop()
id(m) == id(n)
# True, the object is mutated, and m and n still references to the same object.
由于python列表是可变的,所以突变后m和n仍将引用同一对象。而对于像int这样的不可变对象,将创建一个新对象,并且标识符将引用该新对象。
要点是,在您的方案中,由于python列表是可变的,因此只有一个对象。
但是,如果在修改新列表时需要保持原始列表不变,则可以使用copy()方法。
new_list = original_list.copy()
new_list
和original_list
的ID不同。
在此处详细了解可变性:https://medium.com/@meghamohan/mutable-and-immutable-side-of-python-c2145cf72747。
答案 1 :(得分:2)
您必须复制masterList
,否则workingList
只是参考。
如果您的list
不包含其他容器(您的容器没有),则浅拷贝就足够了。进行浅表复制的方法有很多,但是slicing
是最佳选择。
masterList = ["person","woman","man","camera","television"]
workingList = masterList[:] #copy via slice
用于制作浅表副本的其他方式
workingList = masterList * 1
workingList = masterList.copy()
workingList = list(masterList)
workingList = [*masterList]
import copy
workingList = copy.copy(masterList)
如果您的list
确实拥有保存引用的内容(例如其他容器,类等),那么您需要制作一个deepcopy
。
import copy
a = [[1, 2, 3], ['a', 'b', 'c']]
b = copy.deepcopy(a)
答案 2 :(得分:1)
好像我想通了。这两个列表实际上是相同的列表,除非您使用import bs4
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup
my_url = 'https://www.rottentomatoes.com/top/bestofrt/'
# grabbing connection
uClient = uReq(my_url)
page_html = uClient.read()
uClient.close()
# html parser
page_soup = soup(page_html, "html.parser")
# gather movies
containers = page_soup.findAll("table", {"class":"table"})
for container in containers:
movie_rank_container = container.findAll("td", {"class":"bold"})
movie_name_container = container.findAll("a", {"class":"unstyled articleLink"})
movie_rating_container = container.findAll("td", {"class":"right hidden-xs"})
for movie_rank, movie_names, movie_rating in zip(movie_rank_container, movie_name_container, movie_rating_container):
print("Rank: " + movie_rank.text)
print("Name: " + movie_names.text.strip())
print("Rating: " + movie_rating.text)
因此,将前两行替换为:
list.copy()
使一切按预期执行!好吧,我仍然不能说我了解变量作用域是如何整体发挥作用的,但这至少可以解决主要问题。