チューニングについて何も考えずに、名前とその頻度のリストがあると仮定して、プレフィックスをそのプレフィックスを持つ名前のセットにマッピングする辞書を作成し、各セットを上位5つの名前のリストに変換します。周波数。
ここから派生した男の子の名前のリストを使用して、すべての行が整数の出現頻度、いくつかのスペース、そして次のような名前であるテキストファイルを作成します。
8427 OLIVER
7031 JACK
6862 HARRY
5478 ALFIE
5410 CHARLIE
5307 THOMAS
5256 WILLIAM
5217 JOSHUA
4542 GEORGE
4351 JAMES
4330 DANIEL
4308 JACOB
...
次のコードは辞書を構成します。
from collections import defaultdict
MAX_SUGGEST = 5
def gen_autosuggest(name_freq_file_name):
with open(name_freq_file_name) as f:
name2freq = {}
for nf in f:
freq, name = nf.split()
if name not in name2freq:
name2freq[name] = int(freq)
pre2suggest = defaultdict(list)
for name, freq in sorted(name2freq.items(), key=lambda x: -x[1]):
# in decreasing order of popularity
for i, _ in enumerate(name, 1):
prefix = name[:i]
pre2suggest[prefix].append((name, name2freq[name]))
# set max suggestions
return {pre:namefs[:MAX_SUGGEST]
for pre, namefs in pre2suggest.items()}
if __name__ == '__main__':
pre2suggest = gen_autosuggest('2010boysnames_popularity_engwales2.txt')
dictにプレフィックスを付けると、提案が返されます(この場合は頻度とともに、必要に応じて破棄できます。
>>> len(pre2suggest)
15303
>>> pre2suggest['OL']
[('OLIVER', 8427), ('OLLIE', 1130), ('OLLY', 556), ('OLIVIER', 175), ('OLIWIER', 103)]
>>> pre2suggest['OLI']
[('OLIVER', 8427), ('OLIVIER', 175), ('OLIWIER', 103), ('OLI', 23), ('OLIVER-JAMES', 16)]
>>>
試してみません:-)
タイムキラー
実行に時間がかかる場合は、dictを事前に計算してファイルに保存し、必要に応じてpickleモジュールを使用して事前に計算された値をロードします。
>>> import pickle
>>>
>>> savename = 'pre2suggest.pcl'
>>> with open(savename, 'wb') as f:
pickle.dump(pre2suggest, f)
>>> # restore it
>>> with open(savename, 'rb') as f:
p2s = pickle.load(f)
>>> p2s == pre2suggest
True
>>>