Изучайте Python трудным путем #25

#python

#python

Вопрос:

Просматривая приведенное ниже, у меня возник вопрос, на который, как мне кажется, еще не получен ответ (и который не задан на уроке):

Когда я запускаю либо print_first_word , либо print_last_word , результирующий список изменяется с помощью .pop() — однако, когда я запускаю print_first_and_last функцию, список остается неизменным после его завершения. Поскольку print_first_and_last вызываются оба print_first_word и print_last_word , каждый из которых изменяет список через .pop() , почему список не меняется после запуска print_first_and_last ?

  def break_words(stuff):
    '''This function will break up words for us.'''
    stuff.split(' ')
    return stuff.split(' ')

def print_first_word(words):
    '''Prints the first word after popping it off.'''
    word = words.pop(0)
    print word

def print_last_word(words):
    '''Prints last word in the sentence'''
    word = words.pop(-1)
    print word  



def print_first_and_last(sentence):
    '''Prints first and last words in the sentence.'''
    words=break_words(sentence)
    print_first_word(words)
    print_last_word(words)
  

Комментарии:

1. Строка передается по значению (таким образом, создается новая копия), тогда как список передается в функцию по ссылке. В вашем примере предложение не будет изменено при вызове print_first_and_last , поскольку создается новая копия предложения. С другой стороны, если вы передадите список в print_first_and_last , он будет изменен.

2. @dparpyani: В python все передается по ссылке… Некоторый объект просто представляет неизменяемый интерфейс.

3. Можете ли вы привести пример ввода, с помощью которого вы бы вызывали print_first_and_last() , и что насчет конкретного вывода, который вас удивил?

4. @sharth — Допустим, я передаю строку «Сегодня я пойду в магазин» в функцию через переменную Sentence (Предложение = «Сегодня я пойду в магазин»). Функция вернется сегодня и сохранится, чего я и ожидал, но когда я проверяю, какое предложение теперь содержит, оно не изменяется. Это контрастирует с запуском print_first_word (который сначала требует, чтобы я запускал break_words для переменной Sentence, чтобы превратить строку в список), поскольку эта функция удалит 1-ю часть строки через pop (0), так что, когда я увижу, что содержит предложение после его запуска, предложение будет содержать «Я иду в магазин»

5. Не хватило места — но в основном я имею в виду, что поскольку print_first_and_last вызываются оба print_first_word и print_last_word , каждый из которых изменяет список с помощью .pop — для меня интуитивно не имеет смысла, что print_first_and_last оставило бы список неизменным.

Ответ №1:

Первая строка print_first_and_last() является words = break_words(sentence) .

Эта строка создаст новый объект! Этот новый объект будет представлять собой список, содержащий каждое из слов в вашем предложении. Этот новый (несколько временный) объект будет изменен с помощью print_first_word() и print_last_word() .

Если бы мы изменили print_first_and_last() так, чтобы он печатал больше информации, это могло бы быть понятнее:

 def print_first_and_last(sentence):
    words = break_words(sentence)

    print sentence, words
    print_first_word(words)
    print sentence, words
    print_last_word(words)
    print sentence, words
  

Комментарии:

1. И ваш ответ, и Alfasin были полезны, спасибо. Я думаю, у меня были трудности с концептуализацией глобального и локального.

2. Итак, вы практически скопировали мой ответ и расширили свой ответ на два предложения. Это довольно неубедительно…

3. @alfasin: Мы писали его примерно в одно и то же время.

Ответ №2:

Выполняется:

 def print_first_and_last(sentence):
    '''Prints first and last words in the sentence.'''
    words=break_words(sentence)
    print words
    print_first_word(words)
    print words
    print_last_word(words)
    print words

print_first_and_last('This is the first test')
  

выведет:

 ['This', 'is', 'the', 'first', 'test']
This
['is', 'the', 'first', 'test']
test
['is', 'the', 'first']
  

и, как вы можете видеть, список words , очевидно, изменен!