我回答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解釋
關閉-topic:更喜歡使用'next(c)'而不是'c.next()',因爲'next(c)'可以在Python 2.x和3.x上運行。 –
@AshwiniChaudhary我同意,但會指出'next()'作爲內置函數直到2.6,所以如果使用2.5 –