为什么 Python for ... in ...: 语句中的元素使用 byValue 行为?
我似乎无法在任何地方找到对此的解释...
假设我有一个向量 y 初始化为全零:
from numpy import *
y = zeros(5)
它也可以是一个普通的 python 数组,我认为这并不重要。
我注意到 for x in y:
语句的行为是它复制 y 中的每个元素,因此当您修改 x 时,它不会修改 y 。
for x in y:
x = 1
print y
output : array([ 0., 0., 0., 0., 0.])
我的问题如下:为什么会这样?我认为在Python中一切都是byReference,并且很少有byValue传递?
我如何使用引用变量执行以下操作?执行以下操作似乎可行:
for i in range(len(y)):
y[i] = 2*rand()-1
但根据我对 Python 的了解,这是错误的,我相信当我开始使用数千或数百万个值的向量时,它会很慢。
我还能做什么?
I can't seem to find an explanation anywhere for this...
Suppose I have a vector y initialized to all zeroes:
from numpy import *
y = zeros(5)
It could also be a plain python array, I don't think it really matters.
I noticed that the behavior of the for x in y:
statement is that it makes a copy of each element in y, thus when you modify x, it does not modify y.
for x in y:
x = 1
print y
output : array([ 0., 0., 0., 0., 0.])
My question is the following : Why is that so? I thought in Python everything was all byReference and that there is very little byValue passing around?
How could I do the following, using referenced variables? Doing the following seems to work :
for i in range(len(y)):
y[i] = 2*rand()-1
But from what I know about Python, this is wrong and I believe it will be slow when I start using vectors of thousands or millions of values.
What else could I do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以将其替换
为:
如果 y 是 Python 序列(元组、列表、数组等)或 Numpy 数组,则
for x in y:
迭代
y
,设置x
到y
中的每个元素。如果元素是不可变对象,例如
str
、int
、float
或 Numpy 数字类型,那么更改
x
的值不会更改y
中的值。如果元素是可变对象,例如
list
,则改变list
将影响y
。这样想:
x
“指向”一个对象:当您编写赋值语句时:
现在您正在重新分配
x
以“指向”另一个对象:另一方面,如果您使用
x.append(1)
来改变列表,那么x
仍然指向同一个对象(例如列表),但您已经改变了该列表的内容。You can replace this:
with:
If y is a Python sequence (tuple, list, array, etc) or Numpy array,
for x in y:
iterates through
y
, settingx
to each element iny
.If the elements are immutable objects like
str
,int
,float
or a Numpy numeric type,then changing the value of
x
does not change the value iny
.If the elements are mutable objects, such as a
list
, then mutating thelist
will affecty
.Think of it this way:
x
is "pointing" to an object:When you write an assignment statement:
Now you are reassigning
x
to "point" to a different object:On the other hand, if you mutate a list with, say,
x.append(1)
, thenx
still points to the same object (e.g. a list), but you've mutated the contents of that list.Python确实仅使用“引用”。但是 Python(和 Java,可能还有一些其他语言)中所谓的“引用”与“按引用传递”或“C++ 中的引用”不同。当您迭代类似
for i in iterable:
之类的内容时,i
指向当前项。但是,当您在循环中执行i = ...
时,您将用新引用覆盖该引用,而不是替换所指向的对象。所以实际上,Python(以及提到的所有其他语言)都是按值传递的。除了这些值总是(某种)指针。请注意,这不适用于
i.attr = ...
!设置成员则不同,它是一个方法调用(对象的__dict__
的.__setitem__
之一,.__setattr__
或.__setattribute__
代码>据我所知)。因此,如果您在循环中执行i.some_member
,您确实会更改可迭代的项目。另请注意,对于数字或字符串等不可变对象来说,这当然是没有意义的 - 您不可能更改它们。如果您想直接更改例如列表,则需要使用索引(尽管您不需要
range(len(...))
,您可以使用enumerate(the_list)< /code> 并且您将获得索引和当前项目)。还要考虑首先使用列表理解来生成您想要的值。
Python does use "references" only. But what is called "reference" in Python (and Java, and propably a handful of other languages) is not like in "pass-by-reference" or "references in C++". When you iterate over something like
for i in iterable:
,i
points to the current item. But when you doi = ...
in the loop, you're overwriting that reference with a new one instead of replacing the object pointed to. So actually, Python (and all the other languages mentioned) are pass-by-value. Except that those values are always (kind of) pointers.Note that this does not apply for
i.attr = ...
! Setting members is different, it's a method call (one of.__setitem__
of the object's__dict__
,.__setattr__
or.__setattribute__
afaik). So if you didi.some_member
in the loop, you would indeed alter the items of the iterable. Also note that this is of course moot with immutable objects like numbers or strings - you cannot possibly alter those.If you want to alter e.g. a list directly, you need to use indices (although you shouldn't need
range(len(...))
, you can useenumerate(the_list)
and you get indices and the current items). Also consider generating the values you want in the first place by using e.g. a list comprehension.如果我错了,请有人纠正我,但Python中的整数类型是不可变的,这就是为什么当你对向量的元素之一执行某些操作时,你会得到一个新对象。我看了又看,但没有找到任何对这种预感的证实,但是当我尝试
并且我们知道列表是可变的时,我们得到了我们所期望的。
Please someone correct me if I am wrong, but the integer type in Python is not mutable and that is why when you perform some operation on one of the elements of the vector you get back a new object. I looked and looked but haven't found any confirmation of this hunch but when I try
and we know that lists are mutable we get what we expect.
我根本不明白该代码示例有什么错误 - 只要可以从
for
循环所在的范围访问y
,一切都应该很好。I don't see how that code sample is wrong at all - as long as
y
is accessible from the scope that thefor
loop is in, all should be good.