使用 shelve 时出现“TypeError: unhashable type: 'list'”错误
我正在尝试写一段代码,目的是给一个集合添加一个ID,这样我就可以检查这个ID是否已经被使用过,并且把这个集合存储到一个文件里。我一直在用Shelve模块来实现这个功能,但遇到了一些问题。目前我写的代码是这样的:
import praw
import datetime
import shelve
user_agent ='Removed'
r = praw.Reddit(user_agent=user_agent)
submission = r.get_submission(submission_id='11v36o')
r.login('Removed','Removed')
files = shelve.open("PrawTest3.dat", writeback=True)
print "Opened!"
already_done = {}
files["already_done"] = ["a","b"]
files.close()
done = set()
print "Running"
while True:
subreddit = r.get_subreddit('mobilebot')
all_comments = subreddit.get_comments()
files = shelve.open("PrawTest2.dat", writeback=True)
already_done = files["already_done"]
files.close()
for comment in all_comments:
if (comment.body == "Hello") and (comment.id not in already_done) and (comment.id not in done):
files = shelve.open("PrawTest2.dat", writeback=True)
comment.reply(' world!')
already_done = files["already_done"]
already_done.append(comment.id)
files[already_done] = already_done
print "Shelves working"
a = datetime.datetime.now()
b = "%s:%s:%s" % (a.hour,a.minute, a.second)
print "["+b+"]"+"Comment sent!"
files.sync()
files.close()
2 个回答
0
错误出现在这一行:
files[already_done] = already_done
在Python中,list
(列表)是可变的。这意味着它的内容可以改变。而可变类型不能用作字典的键。你需要把你的列表already_done
转换成一个元组,然后再执行files[already_done] = already_done
,这样就能正常工作了。
我说的就是这个意思:
>>> a_dict = {}
>>> a_list = [1, 2, 3]
>>> a_dict[a_list] = "Hello"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> a_tuple = tuple(a_list)
>>> a_dict[a_tuple] = "Hello"
>>> a_dict
{(1, 2, 3): 'Hello'}
不过,如果你只是想让键是字符串"already_done",而不是列表already_done
,那么你应该这样做:
files['already_done'] = already_done
1
Python中的列表不能用作shelve或字典的键,因为它没有哈希值。不过,我觉得你的问题只是这一行的一个拼写错误:
files[already_done] = already_done
我想你想要的是
files["already_done"] = already_done