我正在尝试从csv文件创建数据字典,但遇到了一些麻烦。我已经成功地在我的程序中从两个列表中创建了一个字典,这是我的代码:
playerRank = [[tournamentResults[i],rankingPoints[8]] for i in range(0,len(tournamentResults))]
dict1 = dict(playerRank)
但是,当我尝试用csv文件中的数据创建字典时,我收到错误'TypeError:unhashable type:'list''。以下是我尝试的代码:
totalRank = []
with open("mycsvfile.csv") as players:
for row in csv.reader(players):
totalRank.append(row)
totalRank = [[totalRank[i],0] for i in range(0,len(totalRank))]
dict2 = dict(totalRank)
我不明白为什么第二次尝试制作字典会丢掉错误,而第一本字典是好的?如何解决这个问题的任何帮助将不胜感激!
答案 0 :(得分:1)
问题在于,正如错误消息所示,列表不可清除,这意味着您不能将它们用作dict键。
事实上,原因列表不可清除阻止您将它们用作dict键。列表是可变的,如果你在dict中改变一个键,查找将不再起作用。 (从技术上讲,你可以通过使用基于对象标识的散列函数而不是包含的值来解决这个问题 - 但是==
或者hash
没有用,或者它不会与{{1}对齐}。)
通常的解决方案很简单:元组就像一个字典,除了不可变。因此,如果您的密钥是列表,而不是:
[[key, value] for ...]
...你这样做:
[[tuple(key), value] for ...]
现在,您可以将其传递给dict
,一切正常。
当然,这假设您在创建它们之后想要来改变这些序列。
与此同时,我不确定你为什么要在这里首先使用一系列值,而事实上你可能想要更简单的东西。您的totalRank
是行的列表,您可能只希望每行中有一个列,而不是整个行。在这种情况下,只需这样做:
[[totalRank[0], 0] for ...]
或者,代替totalRank.append(row)
,执行totalRank.append(row[0])
。
(我假设它是你想要的第一列;显然你可以做row[3]
或者其他任何你想要一个不同的列。)
虽然我们正在使用它,但如果你使用的是Python 3或Python 2.7,你可以使用字典理解而不是列表理解来更可读地编写它(并且也是有效的)。而不是:
lst = [[key, value] for ...]
dct = dict(lst)
......就这样做:
dct = {key: value for ...}
如果你使用i in range(len(lst))
的唯一内容是i
,那么你也不必循环lst[i]
;只需循环element in lst
。
全部放在一起:
dct2 = {tuple(rank): 0 for rank in totalRank}
......或者,取决于你想要的东西:
dct2 = {rank[0]: 0 for rank in totalRank}
还有一项改进。这样:
totalRank = []
for row in csv.reader(players):
totalRank.append(row)
只是一种冗长的写作方式:
totalRank = list(csv.reader(players))
或者,如果您只想要第一列:
totalRank = [row[0] for row in csv.reader(players))
所以我们可以将整个循环减少到这个:
with open("mycsvfile.csv") as players:
dict2 = {tuple(row): 0 for row in csv.reader(players)}
......或者,再次:
with open("mycsvfile.csv") as players:
dict2 = {row[0]: 0 for row in csv.reader(players)}