不明白字典为何会变化

1 投票
2 回答
1429 浏览
提问于 2025-04-17 14:09

我正在通过麻省理工学院的开放课程自学Python,遇到了下面这段代码的问题。当我单独运行这个函数或者在另一个函数中运行它时,它会改变原本传入的值'hand',我不太明白为什么。我设置了两个局部变量(hand0和tester)来保存hand的值,第一个是为了保留初始值,第二个是为了进行遍历。然而,三个变量的值都发生了变化,而我只希望'tester'的值改变。除了改变'hand'之外,这个函数的其他部分都按预期工作。

(传入函数的值在设定的参数范围内变化:word_list是一个有效英语单词的列表,word是我在这个函数中替换的字符串用于测试,hand是一个字典,里面存储了字母及其对应的数量。调试代码已被注释掉。)

def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.

    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
    hand0 = hand
    tester = hand
    #display_hand(hand)
    #display_hand(tester)
    word = raw_input('test word: ')
    length = len(word)
    disc = True
    for c in range(length):
        if word[c] in tester.keys() and tester[word[c]]>0:
            #print tester[word[c]]
            #display_hand(hand)
            #display_hand(tester)
            tester[word[c]]=tester[word[c]]-1            
        else:
            #print 'nope'
            disc = False
    if word not in word_list:
        disc = False
    #print disc
    #display_hand(hand)
    #display_hand(tester)
    #display_hand(hand0)
    return disc

2 个回答

5

当你写 tester = hand 的时候,其实并不是在复制 hand,而是创建了一个指向同一个对象的新引用。这意味着你对 tester 所做的任何修改,都会在 hand 上看到。

如果你想解决这个问题,可以使用 tester = hand.copy()http://docs.python.org/2/library/stdtypes.html#dict.copy

10

当你执行 tester = hand 这行代码时,其实你只是创建了一个指向 hand 对象的新引用。换句话说,testerhand 是同一个对象。你可以通过检查它们的 id 来验证这一点:

print id(tester)
print id(hand)  #should be the same as `id(tester)`

或者,你也可以用 is 操作符来比较它们:

print tester is hand  #should return `True`

如果你想复制一个字典,可以使用 .copy 方法:

tester = hand.copy()

撰写回答