今天練習 Python 的時候發現 5.6. Looping Techniques 有個提示
"To change a sequence you are iterating over while inside the loop (for example to duplicate certain items), it is recommended that you first make a copy. Looping over a sequence does not implicitly make a copy."
照著文件上的程式輸入
>>> words = ['a','b','cc']
>>> for w in words:
if len(w)>1:
print('insert',w)
words.insert(0,w)
執行之後就出現
insert cc
insert cc
insert cc
insert cc
insert cc
insert cc
insert cc
insertTraceback (most recent call last):
File "<pyshell#208>", line 3, in <module>
print('insert',w)
File "C:\Python33\lib\idlelib\PyShell.py", line 1318, in write
return self.shell.write(s, self.tags)
KeyboardInterrupt
要 Ctrl+C 才能停下來.
這時候檢查一下哪打錯了, 原來我打
for w in words:
但文件上是
for w in words[:]:
修正之後果然就正常了.
原來 words[:] 是 words 的 copy.
試一下
>>> words is words True >>> words is words[:] False果然沒錯.
在 Java 也是一樣, 如果要改變正在 iterate 的 list 也會有問題
package test;
import java.util.Arrays;
import java.util.List;
public class TestIter {
public static void main(String[] params) {
List words = Arrays.asList("a","b","cc");
for (String w: words) {
if (w.length() > 1) {
System.out.println("insert " + w);
words.add(w);
}
}
}
}
會報錯
insert cc
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at test.TestIter.main(TestIter.java:13)
要改成
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestIter {
public static void main(String[] params) {
List words = Arrays.asList("a","b","cc");
List copyWords = new ArrayList(words);
for (String w: words) {
if (w.length() > 1) {
System.out.println("insert " + w);
copyWords.add(0,w);
}
}
System.out.println(words);
System.out.println(copyWords);
}
}
寫了 Python 跟 Java 這兩段程式, 感覺有微妙的差異...
沒有留言:
張貼留言