我创建了一个字典(因为Keys在utf-8中编码了单词):
import os.path
import codecs
import pickle
from collections import Counter
wordDict = {}
def pathFilesList():
source='StemmedDataset'
retList = []
for r, d, f in os.walk(source):
for files in f:
retList.append(os.path.join(r, files))
return retList
# Starts to parse a corpus, it counts the frequency of each word and
# the date of the data (the date is the file name.) then saves words
# as keys of dictionary and the tuple of (freq,date) as values of each
# key.
def parsing():
fileList = pathFilesList()
for f in fileList:
date_stamp = f[15:-4]
print "Processing file: " + str(f)
fileWordList = []
fileWordSet = set()
# One word per line, strip space. No empty lines.
fw = codecs.open(f, mode = 'r' , encoding='utf-8')
fileWords = Counter(w for w in fw.read().split())
# For each unique word, count occurance and store in dict.
for stemWord, stemFreq in fileWords.items():
if stemWord not in wordDict:
wordDict[stemWord] = [(date_stamp, stemFreq)]
else:
wordDict[stemWord].append((date_stamp, stemFreq))
# Close file and do next.
fw.close()
if __name__ == "__main__":
# Parse all files and store in wordDict.
parsing()
output = open('data.pkl', 'wb')
print "Dumping wordDict of size {0}".format(len(wordDict))
pickle.dump(wordDict, output)
output.close()
当我取消腌制数据并查询此词典时,我无法查询字母词,即使我确定它们在词典中的词,它总是返回false,但是数字查询,它工作正常。这是我如何取消数据和查询:
pkl_file=codecs.open('data.pkl' , 'rb' )
wd=pickle.load(pkl_file)
pprint.pprint(wd) #to make sure the wd is correct and it has been created
print type(wd) #making sure of the type of data structure
pkl_file.close()
#tried lots of other ways to query like if wd.has_key('some_encoded_word')
value= None
inputList= ['اندیمشک' , '16' , 'درحوزه' ]
for i in inputList :
if i in wd :
value = wd[i]
print value
else:
print 'False'
这是我的输出
pa@pa:~/Desktop$ python unpickle.py
False
[('2000-05-07', 5), ('2000-07-05', 2)]
False
所以我很确定编码的单词有问题。
答案 0 :(得分:0)
您的问题是您正在使用codecs.open。该功能专门用于打开文本文件并自动将数据解码为Unicode。 (作为旁注,你通常需要io.open,而不是codecs.open,即使是那种情况。)
要打开一个二进制文件作为字节传递给pickle.load,只需使用内置的open函数,而不是codecs.open。
同时,它通常使整个程序中使用Unicode字符串变得更简单,并且只在边缘使用字节字符串,一旦得到它就解码输入并尽可能晚地编码输出。
此外,您在非Unicode字符串文字中有文字Unicode字符。从来没有,永远这样做过。这是创建隐形mojibake字符串的最可靠方法。当您使用非ASCII字符时,请始终使用Unicode文字(例如u' abc'而不是' abc')。
另外,如果您在源代码中使用非ASCII字符,请始终使用编码声明(当然,请确保您的编辑器使用与编码声明中相同的编码),
另外,请记住,==(和dict lookup)可能无法执行Unicode所需的操作。如果你有一个单词存储在NFC中,并在NFD中查找相同的单词,即使它们代表相同的字符串,这些字符也不会相同。如果不知道您正在使用的确切字符串以及它们如何表示它很难知道这是否是您的代码中的问题,但它在Mac程序中非常常见从文件名或Cocoa GUI应用程序中获取字符串。