这里是初级 python 程序员,我一直在为意外的循环和字典行为撞墙。我正在遍历日志条目的 CSV 文件并将数据解析为类别字典。当我每次通过循环初始化类别字典时,它按预期工作..
像这样:
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%)。
我需要初始化类别字典一次:
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
但是,当我在 for 循环之外初始化类别字典 ANYWHERE 时(无论是在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 原则,但不知道如何找出答案。我花了几个小时才弄清楚问题与类别字典有关。
非常有义务做出任何解释。