今天練習 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) { Listwords = 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 這兩段程式, 感覺有微妙的差異...
沒有留言:
張貼留言