类型错误:不可哈希类型:'list',通过将列表转换为集合进行解决。

4

我有一个来自csv文件的代码列表:

file_path = 'c:\\temp\\list.csv'
csvfile =  open(file_path, 'rb')
reader = csv.reader(csvfile, delimiter=';')
rr = []
for sor in reader:
    if sor[1][0] == '1':
        rr.append(sor)
print type(rr)
<type 'list'>

set (rr)
Traceback (most recent call last):
  File "<pyshell#85>", line 1, in <module>
    set (rr)
TypeError: unhashable type: 'list'

如果我对来自数据库的另一个列表执行相同的操作,它可以正常工作:
cur.execute('select code from mytable')
res = cur.fetchall()
res1 = []
res1.append(x[0] for x in res)
print type(res1)
<type 'list'>
set(res1)
set(['13561255', '11120088'])

rr和res1有何不同?它们都是列表类型。

事实上,我正在通过执行以下操作在数据库中查找不存在于CSV文件中的记录:

result = list(set(res1) - set(rr))

我该如何实现这个(也许更加优化/更快的方式)?
2个回答

9
每个sor都是一个csv行 - 一个由行“单元格”值组成的列表,rr变成了一个列表的列表。列表不能成为集合的项,因为列表是不可哈希的
另一方面,res1是一个字符串值的列表。字符串是可哈希的。
这里有一个示例,说明它们的区别:
>>> l1 = [["1", "2", "3"]]
>>> l2 = ["1", "2", "3"]
>>> 
>>> set(l1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    set(l1)
TypeError: unhashable type: 'list'
>>> set(l2)
set(['1', '3', '2'])

你说得对。我的错误。我应该像处理数据库请求的结果一样处理:res1.append(x[0] for x in res)。 - Gabor

2

这是一个可能有帮助的片段。当从文件中导入时,我使用了“extends”而不是“append”。这可能与从文件中导入有关的细微差别有关。

原始答案:最初的回答

base = ['dunk', 'slump', 'monk']

with open('dummytext.txt', 'r') as c_h_f:
        c_h = []
        for line in c_h_f:
                line = line.strip()
                tokens = line.split(',')
                c_h.extend(tokens)

s1 = set(base)
s2 = set(c_h)

print(s1)
print(s2)

Output...
{'slump', 'monk', 'dunk'}
{' lump', 'bunk', ' slump', ' monk', ' funk', ' junk', ' stump', ' dunk'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接