如何将文本文件上传到字典中(在Python中)?
我正在尝试创建一个算法,能够给用户推荐个性化的书籍。这个算法会根据用户朋友们对书籍的评分,预测用户可能喜欢哪些书。
我用到的两个文本文件是“ratings.txt”和“books.txt”,它们的内容如下:
ratings.txt
"Ben5 0 0 0 0 0 0 1 0 1 -3 5 0 0 0 5 5 0 0 0 0 5 0 0 0 0 0 0 0 0 1 3 0 1 0 -5 0 0 5 5 0 5 5 5 0 5 5 0 0 0 5 5 5 5 -5 Moose5 5 0 0 0 0 3 0 0 1 0 5 3 0 5 0 3 3 5 0 0 0 0 0 5 0 0 0 0 0 3 5 0 0 0 0 0 5 -3 0 0 0 5 0 0 0 0 0 0 5 5 0 3 0 0..." (代表两个用户的评分)
books.txt
"道格拉斯·亚当斯,《银河系漫游指南》
理查德·亚当斯,《兔子坡》
米奇·阿尔博姆,《你在天堂遇见的五个人》
劳里·霍尔斯·安德森,《发声》
玛雅·安吉罗,《我知道笼中鸟为何歌唱》" (代表四本书和作者)
评分系统是这样的:-5表示非常不喜欢,0表示没看过,5表示非常喜欢。
我该如何将这两个文件上传到Python中,并把它们转成字典,以便用于这个相似度算法呢?
提前谢谢你。
4 个回答
读取文件,逐行处理,每一行用空格分开。第一个部分作为键,后面的部分组成一个列表作为值:
data = {}
with open('test.txt', 'r') as f:
for line in f:
line_data = line.split()
data[line_data[0]] = line_data[1:]
print data
打印结果:
{'Ben5': ['0', '0', '0', '0', '0', '0', '1', '0', '1', '-3', '5', '0', '0', '0', '5', '5', '0', '0', '0', '0', '5', '0', '0', '0', '0', '0', '0', '0', '0', '1', '3', '0', '1', '0', '-5', '0', '0', '5', '5', '0', '5', '5', '5', '0', '5', '5', '0', '0', '0', '5', '5', '5', '5', '-5'],
'Moose5': ['5', '0', '0', '0', '0', '3', '0', '0', '1', '0', '5', '3', '0', '5', '0', '3', '3', '5', '0', '0', '0', '0', '0', '5', '0', '0', '0', '0', '0', '3', '5', '0', '0', '0', '0', '0', '5', '-3', '0', '0', '0', '5', '0', '0', '0', '0', '0', '0', '5', '5', '0', '3', '0', '0']}
另外,如果你想把数字当作整数来处理:
data[line_data[0]] = map(int, line_data[1:])
希望这些对你有帮助。
正则表达式可以帮助解决这个问题。
你需要找两个不同的模式 -
import re
s = "Ben5 0 0 0 0 0 0 1 0 1 -3 5 0 0 0 5 5 0 0 0 0 5 0 0 0 0 0 0 0 0 1 3 0 1 0 -5 0 0 5 5 0 5 5 5 0 5 5 0 0 0 5 5 5 5 -5 Moose5 5 0 0 0 0 3 0 0 1 0 5 3 0 5 0 3 3 5 0 0 0 0 0 5 0 0 0 0 0 3 5 0 0 0 0 0 5 -3 0 0 0 5 0 0 0 0 0 0 5 5 0 3 0 0"
name = '(\D+)'
ratings = '((?:-?\d\s)+)'
把这两个模式放在一起,整体的模式就会匹配到两个组。 如果你用同一个模式进行很多次匹配,提前编译这个模式可能会更有效率 -
pattern = name + ratings
regex = re.compile(pattern)
你可以在字符串中逐个查找匹配,并一点一点地构建一个字典 -
d = dict()
for match in regex.finditer(s):
name, ratings = match.groups()
print name, ':', ratings
print '*'*8
d[name] = ratings
print d
>>>
Ben : 5 0 0 0 0 0 0 1 0 1 -3 5 0 0 0 5 5 0 0 0 0 5 0 0 0 0 0 0 0 0 1 3 0 1 0 -5 0 0 5 5 0 5 5 5 0 5 5 0 0 0 5 5 5 5 -5
********
Moose : 5 5 0 0 0 0 3 0 0 1 0 5 3 0 5 0 3 3 5 0 0 0 0 0 5 0 0 0 0 0 3 5 0 0 0 0 0 5 -3 0 0 0 5 0 0 0 0 0 0 5 5 0 3 0
********
{'Moose': '5 5 0 0 0 0 3 0 0 1 0 5 3 0 5 0 3 3 5 0 0 0 0 0 5 0 0 0 0 0 3 5 0 0 0 0 0 5 -3 0 0 0 5 0 0 0 0 0 0 5 5 0 3 0 ', 'Ben': '5 0 0 0 0 0 0 1 0 1 -3 5 0 0 0 5 5 0 0 0 0 5 0 0 0 0 0 0 0 0 1 3 0 1 0 -5 0 0 5 5 0 5 5 5 0 5 5 0 0 0 5 5 5 5 -5 '}
或者你也可以一次性构建这个字典 -
d = dict(regex.findall(s))
试试这个,使用正则表达式和re库:
import re
### assume read all lines from a file
input = '''Ben5 0 0 0 0 0 0 1 0 1 -3 5 0 0 0 5 5 0 0 0 0 5 0 0 0 0 0 0 0 0 1 3 0 1 0 -5 0 0 5 5 0 5 5 5 0 5 5 0 0 0 5 5 5 5 -5 Moose5 5 0 0 0 0 3 0 0 1 0 5 3 0 5 0 3 3 5 0 0 0 0 0 5 0 0 0 0 0 3 5 0 0 0 0 0 5 -3 0 0 0 5 0 0 0 0 0 0 5 5 0 3 0 9
Moos7 5 0 0 0 0 3 0 0 1 0 5 3 0 5 0 3 3 5 0 0 0 0 0 5 0 0 0 0 0 3 5 0 0 0 0 0 5 -3 0 0 0 5 0 0 0 0 0 0 5 5 0 3 0 0'''
output = {}
for (key, val) in re.findall("([a-zA-Z]\w+)\s+(.*?)(?=[a-zA-Z]|$)", input, re.M):
output[key] = val
print output
你提供的信息太少了,但总得从某个地方开始。我假设你的文件中,单词是键,而其他的内容是要存储在列表中的值。如果每一条记录都是用换行符分开的,那么alecxe的解决方案就可以用了。
我正在修改这个程序,让它把你的输入文件当作一个字符串来读取,并且在每一步都加上了strip()方法,以确保换行符被正确处理。
from collections import defaultdict
test = open(someFile).read() # this
mydict = defaultdict(list)
from collections import defaultdict
for item in test.split():
try:
x = int(item.strip())
mydict[currentKey].append(x)
except ValueError:
currentKey = item.strip()
mydict[currentKey] = []
defaultdict(<type 'list'>, {'Ben5': [0, 0, 0, 0, 0, 0, 1, 0, 1, -3, 5, 0, 0, 0, 5, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 1, 0, -5, 0, 0, 5, 5, 0, 5, 5, 5, 0, 5, 5, 0, 0, 0, 5, 5, 5, 5, -5], 'Moose5': [5, 0, 0, 0, 0, 3, 0, 0, 1, 0, 5, 3, 0, 5, 0, 3, 3, 5, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0, 5, -3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 5, 5, 0, 3, 0, 0]})