如何将文本文件上传到字典中(在Python中)?

0 投票
4 回答
1562 浏览
提问于 2025-04-17 23:26

我正在尝试创建一个算法,能够给用户推荐个性化的书籍。这个算法会根据用户朋友们对书籍的评分,预测用户可能喜欢哪些书。

我用到的两个文本文件是“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 个回答

0

读取文件,逐行处理,每一行用空格分开。第一个部分作为键,后面的部分组成一个列表作为值:

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:])

希望这些对你有帮助。

0

正则表达式可以帮助解决这个问题。

你需要找两个不同的模式 -

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))
0

试试这个,使用正则表达式和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
0

你提供的信息太少了,但总得从某个地方开始。我假设你的文件中,单词是键,而其他的内容是要存储在列表中的值。如果每一条记录都是用换行符分开的,那么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]})

撰写回答