3 回答

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超4個(gè)贊
你使這比它需要的更復(fù)雜,這就是挫折的來源。實(shí)際的解決方案比您想象的要簡單得多。
字典跟蹤自己的鍵。你不需要初始化任何東西。如果某個(gè)單詞出現(xiàn)在字典中沒有的字母上,您可以立即添加一個(gè)新鍵。否則,您將使用已經(jīng)存在的列表。
另一點(diǎn)是該string模塊為您提供了在和上拆分的工具。您付出的代價(jià)是必須過濾掉一些空字符串,但這是微不足道的。whitespace punctuation
我建議將中間結(jié)果存儲在sets 而不是列表中以確保唯一性。作為最后一步,您始終可以轉(zhuǎn)換為列表。
并在您的實(shí)用程序函數(shù)中使用返回值而不是打印輸出:
def text_dictionary(file_name):
map = {}
with open(file_name,'r') as file:
for line in file:
for word in line.split(string.whitespace + string.punctuation):
if not word:
continue
word = word.lower()
if word[0] not in map:
map[word[0]] = set()
map[word[0]].add(word)
for key in map:
map[key] = list(map[key])
return map
請注意,除了最基本的訪問之外,我根本沒有使用字典的任何特殊方法或?qū)傩浴?/p>
附錄一:字典轉(zhuǎn)換
最后一個(gè)循環(huán)用就地列表替換集合:它不會創(chuàng)建新的字典對象。你可以用一個(gè)非常相似的循環(huán)來做同樣的事情:
for key, value in map.items():
map[key] = list(item)
通常,在迭代字典時(shí)不應(yīng)該修改它。但是,如果您非常小心地只接觸值而不是鍵,則不會有任何問題,因?yàn)楣1淼牡讓咏Y(jié)構(gòu)不會改變。
創(chuàng)建字典很便宜,因此使用字典理解來創(chuàng)建新映射可能會更快:
map = {key: list(value) for key, value in map.items()}
附錄二:分詞
上面顯示的分詞算法非常簡單。它假定您的文件將只包含表現(xiàn)良好的可打印 ASCII 字符。雖然這可能適用于您的作業(yè),但編寫具有已知潛在問題的代碼讓我感到厭煩,因?yàn)橐院髸泻芏辔粗獑栴}要占用您的時(shí)間。為此,我將介紹幾種使用正則表達(dá)式搜索單詞的替代方法。
第一種選擇是拆分任何不是單詞字符的內(nèi)容。一個(gè)單詞字符(在一個(gè)常規(guī)字符串中)被\w模式匹配,它
匹配 Unicode 單詞字符;這包括可以作為任何語言的單詞一部分的大多數(shù)字符,以及數(shù)字和下劃線。如果使用ASCII標(biāo)志,則僅[a-zA-Z0-9_]匹配。
\wis的倒數(shù)\W,因此您可以將其與 一起使用re.split:
for word in re.split(r'\W+', line):
第二種選擇是第一種的補(bǔ)充。不是在模式上拆分,而是匹配模式并用于re.finditer為您列出單詞:
for word in re.finditer(r'\w+', line):
我是這兩種情況,值得注意的是,最好使用re.compile而不是每次重新編譯模式來預(yù)編譯您選擇的模式。設(shè)置模式的最有效方法是全局設(shè)置,或者在函數(shù)的默認(rèn)參數(shù)中。這樣它只會被評估一次。第二個(gè)最佳選擇是在with塊之前執(zhí)行,因此您至少每個(gè)文件編譯一次,而不是每行一次。全局或函數(shù)內(nèi)定義,看起來像
pattern = re.compile(r'\w') # or r'\W', as you prefer
作為默認(rèn)參數(shù):
def text_dictionary(file_name, pattern=re.compile(r'\w')):
如果您決定修改包含/拆分的字符集,后一種方法可為您提供靈活性。
在任何一種情況下,循環(huán)都將是
for word in pattern.split(line): # or pattern.finditer(line)

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超6個(gè)贊
你可能有點(diǎn)想多了。讓我們列出必要的步驟(按照說明):
創(chuàng)建一個(gè)字典,以字母表中的每個(gè)字母作為鍵,一個(gè)空
set
作為值。將set
用于確保其唯一性。打開文件,去掉標(biāo)點(diǎn)符號并將字符串小寫,然后將其拆分為單詞列表。
遍歷單詞列表中的單詞,并
set
根據(jù)第一個(gè)字母將每個(gè)單詞添加到字典中的對應(yīng)單詞中。將所有集合轉(zhuǎn)換回列表并返回字典。
這是代碼:
import re
import string
def text_dictionary(file_name):
letters = {x: set() for x in string.ascii_lowercase}
with open(file_name,'r') as f:
for word in re.sub(r"\W", " ", f.read().lower()).split():
letters[word[0]].add(word)
return {k: list(v) for k, v in letters.items()}
for k, v in sorted(text_dictionary("file.txt").items()):
print(k, v)
示例輸出(使用您的問題作為輸入):
a ['all', 'a', 'accepts', 'and']
b ['begin']
c ['contains']
d ['do', 'dictionary']
e []
f ['file', 'from', 'function']
g []
h ['here']
i ['im', 'is']
j []
k ['key']
l ['lowercased', 'list', 'letter']
m ['marks', 'make']
n ['no', 'name']
o ['of', 'only']
p ['punctuation']
q []
r ['returns']
s ['supposed', 'sure']
t ['text_dictionaryfile_name', 'the', 'to', 'that']
u ['unique']
v ['values', 'value']
w ['what', 'write', 'where', 'words', 'with']
x []
y []
z []
請注意,我省略了對文件 open 和潛在的錯(cuò)誤處理KeyErrors;如果您打算將其轉(zhuǎn)變?yōu)榭刹渴鸬墓δ?,那么這些將是重要的考慮因素。
添加回答
舉報(bào)