Самостоятельно изучал Python с помощью MIT Open Courseware и столкнулся с проблемой с этим фрагментом кода ниже. Когда я запускаю эту функцию отдельно или в другой функции, она изменяет первоначально переданное значение 'hand', и я не уверен почему. Я установил две локальные переменные (hand0 и tester), первая для сохранения начального значения, а вторая для итерации. Тем не менее, все три изменения, в то время как я ожидаю, что "тестер" сделает это. Кроме мутирующей «руки», функция работает как положено.

(Значения, передаваемые в функцию, варьируются в пределах установленных параметров: 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
0
Phil Saulnier 30 Янв 2013 в 08:37

2 ответа

Лучший ответ

Когда вы делаете tester = hand, вы только создаете новую ссылку на объект hand. Другими словами, tester и hand являются одним и тем же объектом . Вы могли бы увидеть это, если бы проверили их 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()
9
mgilson 30 Янв 2013 в 04:41

Когда вы делаете tester = hand, вы не делаете копию hand, вы делаете новую ссылку на тот же объект. Любые изменения, внесенные вами в tester, будут отражены в hand.

Используйте tester = hand.copy(), чтобы исправить это: http: //docs.python .org / 2 / библиотека / stdtypes.html # dict.copy

4
Mark Ransom 30 Янв 2013 в 04:41