不允许修改Python中的列表迭代器?

发布于 2025-01-08 15:18:55 字数 549 浏览 0 评论 0原文

简单示例:

myList = [1, 2, 3, 4, 5]
for obj in myList:
  obj += 1
print myList

prints

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

while:

myList = [1, 2, 3, 4, 5]
for index in range(0,len(myList)):
  myList[index] += 1
print myList

prints

[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]

结论:

  1. 可以使用全局列表访问就地修改列表 可以
  2. 使用迭代器对象就地修改列表项目

所有示例代码我可以找到使用全局列表访问器来就地修改列表。 修改列表迭代器有这么邪恶吗?

Simple example:

myList = [1, 2, 3, 4, 5]
for obj in myList:
  obj += 1
print myList

prints

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

while:

myList = [1, 2, 3, 4, 5]
for index in range(0,len(myList)):
  myList[index] += 1
print myList

prints

[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]

Conclusion:

  1. Lists can be modified in place using global list access Lists can
  2. List items can NOT be modified in place using the iterator object

All example code I can find uses the global list accessors to modify the list inplace.
Is it so evil to modify a list iterator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

手心的温暖 2025-01-15 15:18:55

obj += 1 未执行您期望的操作的原因是此语句不会就地修改 obj。相反,它会计算新值,并重新绑定变量 obj 以指向新值。这意味着列表的内容保持不变。

一般来说,可以在使用for obj in myList迭代列表时修改列表。例如:

myList = [[1], [2], [3], [4], [5]]
for obj in myList:
  obj[0] += 1
print(myList)

这会打印出:

[[2], [3], [4], [5], [6]]

这与第一个示例之间的区别在于,列表包含可变对象,并且代码就地修改这些对象。

请注意,也可以使用列表理解来编写循环:

myList = [val+1 for val in myList]

The reason obj += 1 does not do what you expect is that this statement does not modify obj in-place. Instead, it computes the new value, and rebinds the variable obj to point to the new value. This means that the contents of the list remain unchanged.

In general it is possible to modify the list while iterating over it using for obj in myList. For example:

myList = [[1], [2], [3], [4], [5]]
for obj in myList:
  obj[0] += 1
print(myList)

This prints out:

[[2], [3], [4], [5], [6]]

The difference between this and your first example is that here, the list contains mutable objects, and the code modifies those objects in-place.

Note that one could also write the loop using a list comprehension:

myList = [val+1 for val in myList]
维持三分热 2025-01-15 15:18:55

我认为您误解了“迭代器对象”是什么。 for 循环不是迭代器对象。出于所有意图和目的,像这样的 for 循环:

myList = [0, 1, 2, 3, 4]
for x in myList:
    print x

执行此操作(但更有效且更简洁):

i = 0
while i < len(myList)
    x = myList[i]
    print x
    i += 1

所以您会看到,一旦下一个循环开始,对 x 所做的任何更改都会丢失,因为x 的值被列表中下一项的值覆盖。

正如其他人所观察到的,在迭代列表时可以更改列表的值。 (但不要改变它的长度!这就是你遇到麻烦的地方。)一种优雅的方法如下:

for i, x in enumerate(myList):
    myList[i] = some_func(x)

更新:了解禁止复制 继续进行 for 循环。在上面的示例中,ix(与 Python 中的所有变量一样)更像是 C/C++ 中的指针。随着 for 循环的进行,obj 指向 myList[0]myList[1] 等,转动。和C/C++指针一样,当指针改变时,所指向对象的属性也不会改变。但也像 C 指针一样,您可以直接修改所指向的内容,因为它不是副本。在 C 中,这是通过取消引用指针来完成的;在 Python 中,这是通过使用可变对象来完成的。这就是为什么 NPE 的答案有效。如果ix甚至是浅拷贝,就不可能做他所做的事情。

您不能直接更改 int 的原因是您可以更改 list 的方式(如 NPE 的答案),因为 int 是不可变。一旦创建了 5 对象,就无法更改其值。这就是为什么在 Python 中传递指向 5 的指针是安全的——不会发生副作用,因为指向的东西是不可变的。

I think you've misunderstood what an "iterator object" is. A for loop is not an iterator object. For all intents and purposes, a for loop like this:

myList = [0, 1, 2, 3, 4]
for x in myList:
    print x

does this (but more efficiently and less verbosely):

i = 0
while i < len(myList)
    x = myList[i]
    print x
    i += 1

So you see, any changes made to x are lost as soon as the next loop starts, because the value of x is overwritten by the value of the next item in the list.

As others have observed, it is possible to alter the value of a list while iterating over it. (But don't change its length! That's where you get into trouble.) One elegant way to do so is as follows:

for i, x in enumerate(myList):
    myList[i] = some_func(x)

Update: It's also important to understand that no copying goes on in a for loop. In the above example, i and x -- like all variables in Python -- are more like pointers in C/C++. As the for loop progresses, obj points at myList[0], myList[1], etc, in turn. And like a C/C++ pointer, the properties of the object pointed to are not changed when the pointer is changed. But also like a C pointer, you can directly modify the thing pointed at, because it's not a copy. In C, this is done by dereferencing the pointer; in Python, this is done by using a mutable object. That's why NPE's answer works. If i and x were even shallow copies, it wouldn't be possible to do what he does.

The reason you can't directly change ints the way you can change lists (as in NPE's answer), is that ints aren't mutable. Once a 5 object is created, nothing can change its value. That's why passing around a pointer to 5 is safe in Python -- no side-effects can occur, because the thing pointed to is immutable.

场罚期间 2025-01-15 15:18:55

for obj in myList: 中,在每次迭代中,objmyList 中元素的(浅)副本。因此,obj 上的更改对 myList 的元素没有任何影响。

它与我的 $obj (@myList) {} 的 Perl 不同

in for obj in myList:, in every iteration, obj is a (shallow) copy of the element in myList. So the change on the obj does nothing to myList's elements.

It's different with the Perl for my $obj (@myList) {}

俏︾媚 2025-01-15 15:18:55

你很困惑。考虑您的第一个片段:

myList = [1, 2, 3, 4, 5]
for obj in myList:
  obj += 1
print a

obj 并不是某种指向列表的神奇指针。它是一个变量,保存对恰好也在 myList 中的对象的引用。 obj += 1 具有增加 obj 中存储的值的效果。然后您的代码不会对该值执行任何操作。

需要明确的是:此代码示例中没有副本。 obj 是一个变量,它保存列表中的一个对象。仅此而已。

You are confused. Consider your first snippet:

myList = [1, 2, 3, 4, 5]
for obj in myList:
  obj += 1
print a

obj is not some kind of magical pointer into the list. It is a variable which holds a reference to an object which happens to also be in myList. obj += 1 has the effect of increasing the value stored in obj. Your code then does nothing with that value.

To be clear: There are no copies in this code example. obj is a variable, which holds an object in the list. That is all.

氛圍 2025-01-15 15:18:55

在第一个示例中,整数被复制到 obj 中并增加 1。
列表没有改变。

如果您要使用类实例并对其执行操作,它就会被更改。

In the first example the integer is copied into obj which is increased by 1.
The list is not changed.

If you would use a class instance and perform operations on it, it would be changed.

作妖 2025-01-15 15:18:55

允许修改列表。您的代码示例非常乱码......

myList = [1, 2, 3, 4, 5]
for index in range(0,len(myList)):
   myList[index] += 1
 print myList

这有效。

Modification in list is allowed. Your code examples arbove are pretty garbled...

myList = [1, 2, 3, 4, 5]
for index in range(0,len(myList)):
   myList[index] += 1
 print myList

This works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文