這裏是初級python程序員,我一直在意料之外的循環和字典行爲上擊敗了我的頭。我正在瀏覽日誌條目的CSV文件並將數據解析爲類別字典。當我初始化類通過循環每次快譯通,它按預期工作..用dict變量和for循環在Python中進行混淆魔術行爲
像這樣:
從這個看log_entries = AutoVivification()
# http://stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries-in-python
def scrublooper(log_file):
for ll in log_file:
# Initialize categories dict every round through the loop
categories = {'requests': {'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 0, 'Pages': 0, 'Content_Files': 0}, 'filter_action': {'re': 0, 'pl': 0, 'bs': 0}}
lld = LogDomain(ll)
domain, hostname, lan_host = lld.domain, lld.hostname, lld.lan_host
mimetypes = url_searcher(Settings.mimetypes, lld.mime_type)
if mimetypes:
category = mimetypes[2]
if not log_entries[lan_host].has_key(domain):
log_entries[lan_host][domain]= categories
log_entries[lan_host][domain]['requests'][category] += 1
print log_entries['192.168.5.210']['google.com']['requests']
print log_entries['192.168.5.210']['webtrendslive.com']['requests']
print log_entries['192.168.5.210']['osnews.com']['requests']
print log_entries['192.168.5.210']['question-defense.com']['requests']
print log_entries['192.168.5.210']['optimost.com']['requests']
輸出是我所期待的:
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 95, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 1, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 2, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 18, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 3, 'Pages': 0, 'Content_Files': 0}
無論其!這是我的問題。我不想每次通過循環初始化類別字典。在這個簡化的例子中,這並不重要,但是在這個程序中,它會導致顯着的性能下降(30%)。
我需要DICT ONCE初始化類:
log_entries = AutoVivification()
categories = {'requests': {'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 0, 'Pages': 0, 'Content_Files': 0}, 'filter_action': {'re': 0, 'pl': 0, 'bs': 0}}
def scrublooper(log_file):
for ll in log_file:
lld = LogDomain(ll)
# etc, etc, etc
然而,當我初始化類別ANYWHERE DICT for循環(無論是在scrublooper功能或簡稱爲log_entries變量之後),輸出外部是:
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 685, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 685, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 685, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 685, 'Pages': 0, 'Content_Files': 0}
{'Content_Visual': 0, 'Content_ProgramsUpdates': 0, 'Content_Text': 685, 'Pages': 0, 'Content_Files': 0}
所有'Conent_Text'值都增加了!這裏發生了什麼?我確信我違反了一些python原則,但不知道該怎麼查找。我花了幾個小時才發現問題與類詞典有關。
非常感謝您的任何解釋。
那麼'categories'實際上在哪裏被操縱?我只看到它正在初始化並正在讀取。對於SO來說,你是否簡化了這一點? –
我不認爲它簡化得太過分了。它始終被分配,從不被操縱。分配給'log_entries'字典鍵/值:'如果不是log_entries [lan_host] .has_key(domain):''log_entries [lan_host] [domain] = categories' – Thinkwell