присвоение списку [:] с использованием понимания списка - PullRequest
0 голосов
/ 02 июля 2018

из этого ответа https://stackoverflow.com/a/1207461/8074522 Я пытаюсь найти разницу между использованием

somelist = [1,2,3,4,5,6,7,8,9]
somelist = [x for x in somelist if x>4]
and 
somelist[:] = [x for x in somelist if x>4]

в своем ответе он говорит

Или, назначив слайсу somelist [:], вы можете изменить существующий список содержит только те элементы, которые вы хотите:

«содержать только» <я могу использовать assign для somelist без нарезки. </p>

Так зачем нужен какой-то список [:] здесь?

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Инструкция как somelist = [1,2,3,4,5,6,7,8,9] создает новый список и присваивает it (весь список) вашей переменной (somelist).

Второй случай, somelist = [x for x in somelist if x>4] - это просто фильтрация . Цикл for присваивает каждому элементу из этого списка временную переменную x.

Затем (внутри этого цикла) if проверяет, соответствует ли этот (текущий) элемент какое-то условие, в вашем случае, будет ли оно больше 4.

Только если это так, этот элемент добавляется в новый массив, который в конечном итоге будет присвоено somelist.

А теперь в чем разница между простым назначением (просто somelist) и назначение среза (до somelist[:]).

Представьте, что изначально было otherList, и вы создали somelist используя простое назначение: somelist = otherList.

На самом деле, второй список не был создан, но somelist может рассматриваться как еще один «указатель» на этот первый список.

Другими словами, otherList и somelist указывают на то же самое внутренний объект (в данном случае массив).

Затем, позже в вашем коде, если вы использовали somelist[:] = ..., вы пишете новый контент на тот же внутренний объект, поэтому этот новый контент виден также с помощью otherList (например, в другой части вашего кода).

Но если вы использовали простое назначение (somelist = ...), то:

  • Создается новый внутренний объект (массив) и somelist точек только к этому.
  • старое содержимое по-прежнему отображается как otherList.

Так, как указал jonrsharpe , решение о том, какой вариант использовать, зависит на то, что действительно нужно вашему приложению.

В простейшем случае, если у вас нет другой переменной, указывающей на «старый» массив, вы можете использовать простое назначение (IMHO более естественный вариант) и старый массив (теперь без ссылки на любую другую переменную) будет мусором собраны.

0 голосов
/ 02 июля 2018

@ jonsharpe дал краткий ответ в комментарии, но проиллюстрировал это наглядно:

Назначить новый список. Теряет ссылку на старый объект списка и создает new one:

>>> lst1 = [[1, 2, 3],[4, 5, 6]]
>>> lst2 = lst1
>>> lst1 = [[7,8,9]]
>>> lst1 is lst2
False
>>> lst1
[[7, 8, 9]]
>>> lst2
[[1, 2, 3], [4, 5, 6]]

Назначить нарезку. Заменяет список (или часть списка, в зависимости от того, что это за фрагмент) на месте, сохраняя тот же объект.

>>> lst1 = [[1, 2, 3],[4, 5, 6]]
>>> lst2 = lst1
>>> lst1[:] = [[7,8,9]]
>>> lst1 is lst2
True
>>> lst1
[[7, 8, 9]]
>>> lst2
[[7, 8, 9]]
...