3 回答

TA贡献1831条经验 获得超4个赞
你使这比它需要的更复杂,这就是挫折的来源。实际的解决方案比您想象的要简单得多。
字典跟踪自己的键。你不需要初始化任何东西。如果某个单词出现在字典中没有的字母上,您可以立即添加一个新键。否则,您将使用已经存在的列表。
另一点是该string模块为您提供了在和上拆分的工具。您付出的代价是必须过滤掉一些空字符串,但这是微不足道的。whitespace punctuation
我建议将中间结果存储在sets 而不是列表中以确保唯一性。作为最后一步,您始终可以转换为列表。
并在您的实用程序函数中使用返回值而不是打印输出:
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
请注意,除了最基本的访问之外,我根本没有使用字典的任何特殊方法或属性。
附录一:字典转换
最后一个循环用就地列表替换集合:它不会创建新的字典对象。你可以用一个非常相似的循环来做同样的事情:
for key, value in map.items():
map[key] = list(item)
通常,在迭代字典时不应该修改它。但是,如果您非常小心地只接触值而不是键,则不会有任何问题,因为哈希表的底层结构不会改变。
创建字典很便宜,因此使用字典理解来创建新映射可能会更快:
map = {key: list(value) for key, value in map.items()}
附录二:分词
上面显示的分词算法非常简单。它假定您的文件将只包含表现良好的可打印 ASCII 字符。虽然这可能适用于您的作业,但编写具有已知潜在问题的代码让我感到厌烦,因为以后会有很多未知问题要占用您的时间。为此,我将介绍几种使用正则表达式搜索单词的替代方法。
第一种选择是拆分任何不是单词字符的内容。一个单词字符(在一个常规字符串中)被\w模式匹配,它
匹配 Unicode 单词字符;这包括可以作为任何语言的单词一部分的大多数字符,以及数字和下划线。如果使用ASCII标志,则仅[a-zA-Z0-9_]匹配。
\wis的倒数\W,因此您可以将其与 一起使用re.split:
for word in re.split(r'\W+', line):
第二种选择是第一种的补充。不是在模式上拆分,而是匹配模式并用于re.finditer为您列出单词:
for word in re.finditer(r'\w+', line):
我是这两种情况,值得注意的是,最好使用re.compile而不是每次重新编译模式来预编译您选择的模式。设置模式的最有效方法是全局设置,或者在函数的默认参数中。这样它只会被评估一次。第二个最佳选择是在with块之前执行,因此您至少每个文件编译一次,而不是每行一次。全局或函数内定义,看起来像
pattern = re.compile(r'\w') # or r'\W', as you prefer
作为默认参数:
def text_dictionary(file_name, pattern=re.compile(r'\w')):
如果您决定修改包含/拆分的字符集,后一种方法可为您提供灵活性。
在任何一种情况下,循环都将是
for word in pattern.split(line): # or pattern.finditer(line)

TA贡献1848条经验 获得超6个赞
你可能有点想多了。让我们列出必要的步骤(按照说明):
创建一个字典,以字母表中的每个字母作为键,一个空
set
作为值。将set
用于确保其唯一性。打开文件,去掉标点符号并将字符串小写,然后将其拆分为单词列表。
遍历单词列表中的单词,并
set
根据第一个字母将每个单词添加到字典中的对应单词中。将所有集合转换回列表并返回字典。
这是代码:
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 和潜在的错误处理KeyErrors;如果您打算将其转变为可部署的功能,那么这些将是重要的考虑因素。
添加回答
举报