2012-11-21 60 views
1

我回答this question,到我的解決方案是下面的(我沒有張貼此答案):函數內部變量未重新在每個函數調用

def wordigit(w): 
    digits = {} 
    c = itertools.count(1) 
    for char in w: 
     if w not in digits: 
      digits[char] = c.next() 
    return ''.join(str(i) for i in (digits[char] for char in w)) 

print ' '.join(wordigit(w) for w in s.split()) 

乍一看,這看起來正確的。但我得到了一個錯誤的結果:

In [236]: ' '.join(wordigit(w) for w in s.split()) 
Out[236]: '12345 14345 33345' # notice the numbers in the second "word". 1-4 is not a legal progression for itertools.count. It should have been 12324 instead of 14345 

我在IPython中開發了這個解決方案。認爲這可能是IPython在底層做了一些優化的一個錯誤,我啓動了一個python解釋器來看看它說了些什麼。我也認爲列表理解可能會導致一些異常行爲。於是,我就打電話wordigit兩次 - 每兩個不相等的字符串的一次,得到如下結果:

>>> def wordigit(w): 
...  digits = {} 
...  c = itertools.count(1) 
...  for char in w: 
...   if w not in digits: 
...    digits[char] = c.next() 
...  return ''.join(str(i) for i in (digits[char] for char in w)) 
... 
>>> wordigit('areyo') 
'12345' 
>>> wordigit('uanap') 
'14345' 

如此看來,即使我創建函數內的itertools.count對象(因此功能應該重新創建每次運行),它在函數返回後以某種方式持續存在,並且在再次調用函數時不重新初始化而被重用。同樣,很顯然,wordigit中的dict「數字」也是如此。

這是怎麼發生的?不知何故,這種行爲對我來說沒有意義。

我注意到IPython的這種行爲與Python 2.7.1和Python的清新2.7.3解釋

+1

關閉-topic:更喜歡使用'next(c)'而不是'c.next()',因爲'next(c)'可以在Python 2.x和3.x上運行。 –

+0

@AshwiniChaudhary我同意,但會指出'next()'作爲內置函數直到2.6,所以如果使用2.5 –

回答

4

這看起來不正確:

for char in w: 
    if w not in digits: 
     ^^^ 

可能:

for char in w: 
    if char not in digits: 
     ^^^^ 
+0

,那麼你運氣不好。你是對的。修好了......和天哪!那是一個愚蠢的錯誤 – inspectorG4dget