處理正在 iterate 的 dictionary


今天練習 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 這兩段程式, 感覺有微妙的差異...

沒有留言:

張貼留言

別名演算法 Alias Method

 題目 每個伺服器支援不同的 TPM (transaction per minute) 當 request 來的時候, 系統需要馬上根據 TPM 的能力隨機找到一個適合的 server. 雖然稱為 "隨機", 但還是需要有 TPM 作為權重. 解法 別名演算法...