我正在学习脚本语言 python。我对 Java 相当了解。我正在尝试将一段代码从 Java 翻译成 python。但他们行为不规律(或者我的理解可能完全错误) 我在 Java 中有以下代码,我在其中无限期地向 ArrayList 添加元素。 所以这会导致内存不足错误,我预计:
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 翻译相同的代码:
lst = []
lst.append(5)
lst.append(4)
for i in range(len(lst)):
lst.append(5)
print lst
这里我得到输出:[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 循环内的每次迭代中,我都在增加列表大小,因此迭代应该永远正确吗?
请您参考如下方法:
python for 循环评估产生可迭代的表达式,仅在其上循环一次。您可以在循环中操作 lst 对象,而不会影响 for 循环的结果。这不同于 Java for 构造(它与 Python for 语句的构造非常不同,后者实际上是一个 Foreach 构造),它计算 3 个关联的表达式对于每次迭代。
在您的第一个示例中,您创建了一个 range() 结果,一旦创建,它就不会在每次循环迭代时更新。
在第二个示例中,您使用全长切片 (lst[:]) 创建了 lst 的副本,供循环迭代。不会为每次循环迭代重新创建副本。
但是这里有一个警告。 for 循环调用 iter()在要迭代的对象上。对于列表对象,生成的列表迭代器确实保留对原始列表的引用以及迭代索引。每次 for 循环推进迭代器(在其上调用 next()),迭代索引递增并查找原始列表,直到索引等于列表长度。如果您不断向循环中的列表添加内容,会创建一个无限循环。
如果您不创建列表的副本进行迭代,您可以看到这一点:
>>> 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 在循环中被扩展,如果我没有在循环中添加长度限制,这会一直持续下去。
