Что означает ссылка в Python (применительно к спискам, в частности)? - PullRequest
1 голос
/ 30 мая 2020

Я начал изучать python и обнаружил что-то странное и хотел спросить об этом.

Ниже приведена кодировка, и я выделил часть функции, о которой у меня есть вопрос.

В конце функции def add_attraction(destination, attraction) написано только return без указания значения он возвращается. Но он по-прежнему возвращает значение, хранящееся в переменной attractions_for_destination. Как это могло быть?

Другими словами, насколько я понимаю, attractions_for_destination = attractions[destination_index] этот код сохраняет значение attractions[destination_index] во вновь созданной переменной attractions_for_destination. И через attractions_for_destination.append(attraction) этот код добавляет изменение во вновь созданную переменную. Но в итоге изменилась переменная attractions. Короче говоря, изменения добавляются к attractions_for_destination, но я не понимаю, как attractions также изменены.

Я задал этот вопрос где-то еще на inte rnet, и кто-то помог мне и кое-что упомянул о реферировании. На самом деле я этого не понимаю, потому что по-прежнему значение добавляется к переменной attractions_for_destination, а не к переменной attractions, но консоль показывает, что добавлена ​​переменная attractions. Может кто мне это прояснить?

destinations = ["Paris, France", 
"Shanghai, China", "Los Angeles, USA", "Sao Paulo, Brazil", "Cairo, Egypt"]

test_traveler = ['Erin Wilkes', 'Shanghai, China', ['historical site', 'art']]

#destination index
destination_index = 0
def get_destination_index(destination):
  destination_index = destinations.index(destination)
  return destination_index

#traveler current destination
def get_traveler_location(traveler):
  traveler_destination = traveler[1]
  traveler_destination_index = get_destination_index(traveler_destination)
  return traveler_destination_index

#finding traveler current destination index
test_destination_index = get_traveler_location(test_traveler)

attractions = [[] for destination in destinations]

def add_attraction(destination, attraction):
  try:
    destination_index = get_destination_index(destination)
  except ValueError:
    return 
  ***attractions_for_destination = attractions[destination_index]
  attractions_for_destination.append(attraction)
  return*** 

add_attraction("Los Angeles, USA", ['venice Beach' , ['beach']]) 

print(attractions)

1 Ответ

3 голосов
/ 30 мая 2020

attractions - это список списков.

В операторе присваивания:

attractions_for_destination = attractions[destination_index]

Это связывает имя attractions_for_destination с одним из внутренних списков, которые являются элементами attractions список. То есть он не копирует его, а, скорее, имя attractions_for_destination теперь относится к точно такому же объекту списка в памяти. Таким образом, когда этот список изменяется (в данном случае путем вызова его метода append), измененное значение можно увидеть, независимо от того, какая ссылка на список используется для доступа к нему. В частности, по-прежнему существует ссылка на тот же список, что и элемент списка attractions, поэтому измененное значение подсписка видно, когда вы выполняете print(attractions).

Две строки которые вы выделили, имеют тот же общий эффект, что и простое выполнение:

    attractions[destination_index].append(attraction)

Помимо ответа на прямой вопрос, я бы также добавил, что в этом коде список находится в том же порядке, что и другой список (в данном случае attractions и destinations) - плохой выбор типа данных, и было бы лучше использовать словарь. Например:

attractions = dict((destination, []) for destination in destinations)

def add_attraction(destination, attraction):
    try:
        attractions[destination].append(attraction)
    except KeyError:
        return
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...