谁是你爸爸的python计划

时间:2016-03-07 22:13:46

标签: python

我一直在尝试从字典中删除元素或对时遇到问题。当你输入儿子的名字时,它应该删除父亲和儿子,但它总是会产生这个错误:

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()

4 个答案:

答案 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中,listdict是可变的。这意味着当你这样做时:

i = 1
i = 2

i仅是对值int实例化的1对象的引用。当您将2分配给i时,前一个值为1的实例将被遗忘,并将由垃圾收集器收集。但是当你这样做时:

l = []
l.append(1)
l.append(2)

然后您已经从l引用了list对象,您修改后该对象包含两个值:12。所以现在,想象一下你想在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中查找列表,列表无法进行哈希处理!