我一直在尝试从字典中删除元素或对时遇到问题。当你输入儿子的名字时,它应该删除父亲和儿子,但它总是会产生这个错误:
Traceback (most recent call last):
File "C:\Users\jam7733\Desktop\whos ur daddy.py", line 23, in <module>
daddy()
File "C:\Users\jam7733\Desktop\whos ur daddy.py", line 20, in daddy
if del_son in fathers:
TypeError: unhashable type: 'list'
这是我的代码:
def daddy():
fathers = {'johnny':'john Dupuis','alex':'jordan belfort','henry':'daniel plainview','mike':'brian cranston','max':'fred man','benny':'nick flick','billy':'robert kardashian'}
choice = raw_input("do you want to: a)add a father-son pair,b)delete a pair, c)replace a pair,d)look up father-son pair, or e)look for grandfather")
if choice == 'd':
name = raw_input("what is the first name of the child? ")
if name in fathers:
print name,"is the child of",fathers[name]
else:
print "sorry, we do not have this name listed, please try again."
daddy()
if choice == "a":
new_dad = raw_input("what is the name of the new dad?")
new_son = raw_input("what is the name of the son?")
fathers[new_dad]=new_son
if choice == "b":
print"Here are the names of the fathers that you can delete: "
print fathers
del_son = raw_input("what father/son pair do you want to delete?(type first name of son").split(" ")
if del_son in fathers:
del fathers[del_son]
daddy()
答案 0 :(得分:1)
如@kindall和@PadraicCunningham的评论所述,del_son
是一个列表:
del_son = raw_input("what father/son pair do you want to delete?(type first name of son").split(" ")
因为在这里你用空格分割它的名字。鉴于你的代码,我认为这是一个错误,或者当你写这行时你不明白。
在python中,您不能使用list
作为dict
的键,因为dict
需要其所有键都是不可变的,以确保给定键是独特的。在python中,list
和dict
是可变的。这意味着当你这样做时:
i = 1
i = 2
i
仅是对值int
实例化的1
对象的引用。当您将2
分配给i
时,前一个值为1
的实例将被遗忘,并将由垃圾收集器收集。但是当你这样做时:
l = []
l.append(1)
l.append(2)
然后您已经从l
引用了list
对象,您修改后该对象包含两个值:1
和2
。所以现在,想象一下你想在dict中用list
索引一个值,你可以这样做:
d = {}
l1 = [3,1]
l2 = [3,4]
d[l1] = 'foo'
d[l2] = 'bar'
天真地,没有理由为什么这样做不会成为:
{[1,4]: 'foo', [3,4]: 'bar'}
但是如果你这样做了:
l1.remove(1)
l1.append(4)
那么dict
怎么可能仍然有效,因为dict
会变成:{/ p>
{[3,4]: 'foo', [3,4]: 'bar'}
希望你得到的tuple
类型是不可变的并且可以删除:
d = {(3,1): 'foo', (3,4): 'bar}
所以你可能只想不.split()
它。您可能希望strip()
它(它将删除任何前导和尾随空白字符)。
所以你走了:
del_son = raw_input("what father/son pair do you want to delete?(type first name of son").strip()
if del_son in fathers.keys():
del fathers[del_son]
我的两分钱:为了使其更明确,您最好使用
del_son in fathers.keys()
。它实际上和你写的一样,只是为了方便阅读它更容易,因为del_son in fathers
具有误导性(可以读作:&#34;是编码器删除一个父亲名单中的儿子?WTH?&#34; ,而添加.keys()
会读取&#34;啊!编码员正在从儿子身上移除父亲→父亲映射!有道理!&#34; )
HTH
答案 1 :(得分:0)
字典不能有类型列表的键,因为键必须是不可变的。但是,您可以使用另一个不可变类型(如元组),但这是更大问题的外围。问题是你在没有必要的时候分割了儿子的名字。
del_son = raw_input("what father/son pair do you want to delete?(type first name of son").split(" ")
这总是会返回一个列表。当您输入:
del fathers[del_son]
它使用列表的键索引父亲dict,这是不允许的。只需删除raw_input之后的.split(" ")
即可。
答案 2 :(得分:0)
对于del_son
输入,您要指定raw_input("...").split(" ")
的结果。 split()
会返回一个列表。因此del_son
成为一个列表,不能用于字典键。
在这种情况下,您想要的只是拆分的第一个结果,因此raw_input("...").split(" ")[0]
:
del_son = raw_input("what father/son pair ...").split(" ")[0]
这是返回列表中的第一项(索引0)。然后del_son
只是第一个元素和一个字符串。
如果raw_input...split...[0]
似乎太长,您可以将该行留在现在,并将下一位更改为:
if del_son[0] in fathers:
del fathers[del_son[0]]
答案 3 :(得分:0)
你对自己的索引感到困惑,从而将你的dict混淆成一个列表,因为它现在是可变的。在dict中查找列表,列表无法进行哈希处理!