ここのジュニア python プログラマーであり、予想外の for ループと辞書の動作にレンガの壁に頭をぶつけてきました。ログエントリの CSV ファイルをループして、データを解析してカテゴリ辞書にします。ループのたびにカテゴリ dict を初期化すると、期待どおりに動作します。
そのようです:
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}
でも!これが私の問題です。ループのたびにカテゴリ dict を初期化したくありません。この単純化された例では問題ではありませんが、このプログラムの将来的には、パフォーマンスが大幅に低下します (30%)。
カテゴリ dict を一度初期化する必要があります。
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
ただし、カテゴリ 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の原則に違反していると確信していますが、何をどのように見つけるべきかわかりません。問題がカテゴリ辞書に関連していることを理解するのに何時間もかかりました。
どんな説明にも大いに感謝します。