このファイル形式はcsv
、標準ライブラリのモジュールが処理するように設計されたものです。ただし、辞書キーは1つのものにしかマップできないため、辞書を希望どおりにレイアウトすることはできません。この制限を回避する簡単な方法は、以下のサンプルコードと出力に示すように、各電話番号をリストのリストにマップすることです。
import csv
result = {}
with open('numbers.txt', 'rb') as input:
for phone_number, name, address in csv.reader(input):
if phone_number in result:
result[phone_number] += [[name, address]]
else:
result[phone_number] = [[name, address]]
print result
出力:
{'555-328382': [['john paul', '85 big road']],
'555-457645': [['zac fry', "45 tony's rd"], ['kim fry', "45 tony's rd"]],
'555-667282': [['bill higs', '67 hilltop']]}
内部ループ内のコードは、のサブクラスであるfor
と呼ばれる別の標準ライブラリクラスを使用して簡略化できます。存在しない値が参照されるたびに、辞書エントリを指定されたデフォルト値に自動的に初期化します。この例にどのように適用できるかを次に示します。defaultdict
dict
import collections
import csv
result = collections.defaultdict(list)
with open('numbers.txt', 'rb') as input:
for phone_number, name, address in csv.reader(input):
result[phone_number] += [[name, address]]
print result
2番目のバージョンの出力:
defaultdict(<type 'list'>, {
'555-328382': [['john paul', '85 big road']],
'555-457645': [['zac fry', "45 tony's rd"], ['kim fry', "45 tony's rd"]],
'555-667282': [['bill higs', '67 hilltop']]})
defaultdict
それ以外の点では、オブジェクトは、コードの残りの部分で通常の辞書と同じように使用できます。