为什么列表在python和Java中的行为不同?

2024-10-05 10:01:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习脚本语言python。我很懂Java。我正在尝试将一段代码从Java翻译成python。但他们行为反常(或者我的理解可能完全错误) 我用Java编写了以下代码,其中无限期地向ArrayList添加元素。 所以这会导致outofmemory错误,我预计:

import java.util.*;
public class Testing{
public static void main(String[] args){
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(5);
        list.add(4);
        for (int i=0;i<list.size();i++){
            list.add(5);
        }
}
}

现在用相同的python代码翻译:

^{pr2}$

这里我得到了输出:[5, 4, 5, 5]

在我看来,这个列表不是作为对python中的for循环的引用传递的吗?在

同样的

>>> l=[1,2,3]
>>> for i in l[:]:
...    l.append(4)
...    print l
... 
[1, 2, 3, 4]
[1, 2, 3, 4, 4]
[1, 2, 3, 4, 4, 4]

for循环内的每次迭代中,我都在增加列表大小,所以迭代应该永远正确吗?在


Tags: 代码add元素列表for错误integerjava
3条回答

> is the list not passed as reference to the for-loop in python?

在Python中,所有对象都是通过引用传递的,而在Python中,所有对象都是一个对象。(Java原语值不是,但即使是普通的整型值和浮点值也是Python中的对象。)

> in each iteration inside for-loop, I am increasing the list size, so the iteration should go forever correct?

您正在增加l的大小,这是正确的,但是l[:]只计算一次并生成l的一个浅副本。该副本不会在循环中更改,因此在循环中对l的更改不会更改循环变量将采用的值集。在

在那个循环中将l[:]改为l,然后您将看到大量输出。在

python for循环计算产生iterable的表达式,该表达式只在该表达式上循环一次。您可以在循环中操作lst对象,而不会影响for循环的结果。这不同于Java for构造(它与Pythonfor语句非常不同,它实际上是一个Foreach构造),它为每个迭代计算3个相关的表达式。在

在第一个示例中,您创建了一个range()结果,一旦创建,它就不会为每个循环迭代更新。在

在第二个示例中,您使用一个全长切片(lst[:])创建了一个lst的副本,以便循环进行迭代。不会为每个循环迭代重新创建副本。在

不过,这里有一个警告。for循环对要迭代的对象调用^{}。对于列表对象,结果列表迭代器保留对原始列表的引用以及迭代索引。每当for循环向前推进迭代器(对其调用^{}),迭代索引就会递增并在原始列表中查找,直到索引等于列表长度。如果你继续在循环中添加到列表中,那么将创建一个无限循环。在

如果您创建要迭代的列表副本,则可以看到:

>>> L = [1, 2, 3]
>>> for i in L:
...     L.append(4)
...     print L
...     if len(L) > 30:
...         break
... 
[1, 2, 3, 4]
[1, 2, 3, 4, 4]
[1, 2, 3, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
[1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]

在这里,为L创建的迭代器继续生成下一个元素,因为L在循环中被扩展,如果我没有在循环中添加长度限制,这将一直持续下去。在

range(len(lst))创建一次范围,然后迭代该范围,而在java中,list.size()在每次迭代中都会求值

相关问题 更多 >

    热门问题