我最初认为 Python 是一种纯粹的传递引用语言。
来自 C/C++ 的我不禁想到内存管理,我很难把它从脑海中抹去。所以我试图从 Java 的角度来考虑它,并将除原语之外的所有内容都视为引用传递。
问题:我有一个列表,其中包含一组用户定义类的实例。
如果我使用 for-each 语法,即:
for member in my_list:
print(member.str);
member
是否等同于对对象的实际引用?
是否相当于做:
i = 0
while i < len(my_list):
print(my_list[i])
i += 1
我认为不是,因为当我要进行替换时,它不起作用,也就是说,这不起作用:
for member in my_list:
if member == some_other_obj:
member = some_other_obj
在列表中进行简单的查找和替换。可以在for-each循环中完成吗,如果可以,如何?否则,我是否只需要使用随机访问语法(方括号),或者两者都不起作用,我需要删除条目并插入一个新条目?即:
i = 0
for member in my_list:
if member == some_other_obj:
my_list.remove(i)
my_list.insert(i, member)
i += 1
最佳答案
回答这个问题很好,因为这些评论使我对 Python 变量的理解有所提高。
如注释中所述,当您使用 for member in my_list
之类的内容遍历列表时,member
变量将绑定(bind)到每个连续的列表元素。但是,在循环中重新分配该变量不会直接影响列表本身。例如,此代码不会更改列表:
my_list = [1,2,3]
for member in my_list:
member = 42
print my_list
输出:
[1, 2, 3]
如果要更改包含不可变类型的列表,则需要执行以下操作:
my_list = [1,2,3]
for ndx, member in enumerate(my_list):
my_list[ndx] += 42
print my_list
输出:
[43, 44, 45]
如果你的列表中包含可变对象,可以直接修改当前的member
对象:
class C:
def __init__(self, n):
self.num = n
def __repr__(self):
return str(self.num)
my_list = [C(i) for i in xrange(3)]
for member in my_list:
member.num += 42
print my_list
[42, 43, 44]
请注意,您仍然没有更改列表,只是修改了列表中的对象。
您可能会从阅读 Naming and Binding 中受益.
关于Python 列表和 foreach 访问(在内置列表中查找/替换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7423118/